﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using Styx;
using Styx.Common;
using Styx.CommonBot;
using Styx.Helpers;
using Styx.Pathing;
using Styx.TreeSharp;
using Styx.WoWInternals;
using Styx.WoWInternals.WoWObjects;
using Styx.WoWInternals.World;
using Action = Styx.TreeSharp.Action;

namespace TuanHA_Combat_Routine
{
    public partial class Classname
    {
        #region ArcaneTorrent

        private static WoWUnit UnitArcaneTorrent;

        private static bool GetUnitArcaneTorrent()
        {
            UnitArcaneTorrent = null;

            ////using (StyxWoW.Memory.AcquireFrame())
            {
                if (InBattleground || InArena)
                {
                    UnitArcaneTorrent = NearbyUnFriendlyPlayers.FirstOrDefault(
                        unit => BasicCheck(unit) &&
                                (THSettings.Instance.InterruptAll ||
                                 THSettings.Instance.InterruptTarget &&
                                 Me.CurrentTarget != null &&
                                 unit == Me.CurrentTarget ||
                                 THSettings.Instance.InterruptFocus &&
                                 Me.FocusedUnit != null &&
                                 unit == Me.FocusedUnit) &&
                                InterruptCheck(unit, THSettings.Instance.RebukeMs, false) &&
                                Attackable(unit, 8));
                }
                else
                {
                    UnitArcaneTorrent = NearbyUnFriendlyUnits.FirstOrDefault(
                        unit => BasicCheck(unit) &&
                                (THSettings.Instance.InterruptAll ||
                                 THSettings.Instance.InterruptTarget &&
                                 Me.CurrentTarget != null &&
                                 unit == Me.CurrentTarget ||
                                 THSettings.Instance.InterruptFocus &&
                                 Me.FocusedUnit != null &&
                                 unit == Me.FocusedUnit) &&
                                FarFriendlyUnits.Contains(unit.CurrentTarget) &&
                                InterruptCheck(unit, THSettings.Instance.RebukeMs, false) &&
                                Attackable(unit, 8));
                }
            }

            return BasicCheck(UnitArcaneTorrent);
        }

        private static void ArcaneTorrentVoid()
        {
            if (THSettings.Instance.AutoRacial &&
                LastInterrupt < DateTime.Now &&
                //S//SSpellManager.HasSpell("Arcane Torrent") &&
                GetUnitArcaneTorrent() &&
                CanCastCheck("Arcane Torrent", true))
            {
                if (Me.IsCasting || Me.IsChanneling)
                {
                    SpellManager.StopCasting();
                }

                while (UnitArcaneTorrent.CurrentCastTimeLeft.TotalMilliseconds >
                       THSettings.Instance.RebukeMs + MyLatency)
                {
                    Logging.Write("Waiting for Arcane Torrent");
                }

                if (UnitArcaneTorrent.IsCasting || UnitArcaneTorrent.IsChanneling)
                {
                    CastSpell("Arcane Torrent", Me, "Arcane Torrent");
                    LastInterrupt = DateTime.Now + TimeSpan.FromMilliseconds(1500);
                }
            }
        }

        #endregion

        #region Ardent Defender

        private static Composite ArdentDefender()
        {
            return new Decorator(
                ret =>
                //S//SSpellManager.HasSpell("Ardent Defender") &&
                ////!Me.Mounted &&
                Me.Combat &&
                !MeHasAura("Divine Shield") &&
                HealWeightMe <= THSettings.Instance.ArdentDefenderHP &&
                CanCastCheck("Ardent Defender", true),
                new Action(delegate
                    {
                        CastSpell("Ardent Defender", Me);
                        return RunStatus.Failure;
                    }));
        }

        #endregion

        #region AttackASAPRotation

        private static Composite AttackASAPRotationInstantComp()
        {
            return new Decorator(
                ret => GetUnitAttackASAP(),
                new PrioritySelector(
                    new Decorator(
                        ret =>
                        THSettings.Instance.CrusaderStrikeHoly &&
                        //S//SSpellManager.HasSpell("Crusader Strike") &&
                        FacingOverride(UnitAttackASAP) &&
                        Attackable(UnitAttackASAP, 5) &&
                        CanCastCheck("Crusader Strike"),
                        new Action(delegate
                            {
                                CastSpell("Crusader Strike", UnitAttackASAP);
                                UnitAttackASAP = null;
                            })),
                    new Decorator(
                        ret =>
                        THSettings.Instance.JudgmentHolyAttack &&
                        //S//SSpellManager.HasSpell("Judgment") &&
                        !InvulnerableSpell(UnitAttackASAP) &&
                        Attackable(UnitAttackASAP, 30 + _bonusJudgementRange) &&
                        CanCastCheck("Judgment"),
                        new Action(delegate
                            {
                                CastSpell("Judgment", UnitAttackASAP);
                                UnitAttackASAP = null;
                            })),
                    new Decorator(
                        ret =>
                        !//S//SSpellManager.HasSpell("Eternal Flame") &&
                        //S//SSpellManager.HasSpell("Word of Glory") &&
                        HasGlyph.Contains("41107") && //Glyph of Harsh Words
                        (PlayerHolyPower >= 1 || MeHasAura(" Divine Purpose")) &&
                        BasicCheck(UnitHeal) &&
                        HealWeightUnitHeal > THSettings.Instance.WordofGloryHolyHP &&
                        Attackable(UnitAttackASAP, 40) &&
                        !InvulnerableSpell(UnitAttackASAP) &&
                        FacingOverride(UnitAttackASAP) &&
                        CanCastCheck("Word of Glory"),
                        new Action(delegate
                            {
                                SafelyFacingTarget(UnitAttackASAP);
                                CastSpell("Word of Glory", UnitAttackASAP);
                                UnitAttackASAP = null;
                            })),
                    new Decorator(
                        ret =>
                        THSettings.Instance.Exorcism &&
                        //S//SSpellManager.HasSpell("Exorcism") &&
                        FacingOverride(UnitAttackASAP) &&
                        !InvulnerableSpell(UnitAttackASAP) &&
                        (PlayerHolyPower < Me.MaxHolyPower || GetDistance(UnitAttackASAP) > 5) &&
                        Attackable(UnitAttackASAP, 40) &&
                        CanCastCheck("Exorcism"),
                        new Action(delegate
                            {
                                SafelyFacingTarget(UnitAttackASAP);
                                CastSpell("Exorcism", UnitAttackASAP);
                                UnitAttackASAP = null;
                            })),
                    new Decorator(
                        ret =>
                        //_lastCastSpell != "Holy Shock" &&
                        THSettings.Instance.HolyShockOffensive &&
                        //S//SSpellManager.HasSpell("Holy Shock") &&
                        (UnitHeal == null || HealWeightUnitHeal > THSettings.Instance.DoNotHealAbove) &&
                        !InvulnerableSpell(UnitAttackASAP) &&
                        FacingOverride(UnitAttackASAP) &&
                        Attackable(UnitAttackASAP, 40) &&
                        CanCastCheck("Holy Shock"),
                        new Action(delegate
                            {
                                SafelyFacingTarget(UnitAttackASAP);
                                CastSpell("Holy Shock", UnitAttackASAP);
                                //UnitAttackASAP = null;
                            }))
                    ))
                ;
        }

        private static Composite AttackASAPRotationCastComp()
        {
            return new Decorator(
                ret => GetUnitAttackASAP(),
                new PrioritySelector(
                    new Decorator(
                        ret =>
                        THSettings.Instance.Denounce &&
                        //S//SSpellManager.HasSpell("Denounce") &&
                        !IsMoving(Me) &&
                        Attackable(UnitAttackASAP, 30) &&
                        !InvulnerableSpell(UnitAttackASAP) &&
                        FacingOverride(UnitAttackASAP) &&
                        CanCastCheck("Denounce"),
                        new Action(delegate
                            {
                                WoWMovement.ConstantFace(UnitAttackASAP.Guid);
                                CastSpell("Denounce", UnitAttackASAP);
                                UnitAttackASAP = null;
                            }))
                    ));
        }

        #endregion

        #region AttackRotationHoly

        private static WoWUnit UnitJudgment;

        private static bool GetUnitJudgment()
        {
            //using (StyxWoW.Memory.AcquireFrame())
            {
                ///if (!Me.Mounted ||
                ///    !SpellManager.HasSpell("Judgment"))
                ///{
                ///    return false;
                ///}

                UnitJudgment = null;

                if (THSettings.Instance.JudgmentBurdenofGuilt &&
                    SpellManager.HasSpell("Burden of Guilt"))
                {
                    UnitJudgment = NearbyUnFriendlyPlayers.OrderBy(CountDebuffRootandSnareMechanic).FirstOrDefault(
                        unit => BasicCheck(unit) &&
                                (InBattleground || InArena) &&
                                !InvulnerableSpell(unit) &&
                                Attackable(unit, 30 + _bonusJudgementRange));
                }

                if (THSettings.Instance.JudgmentLongArmoftheLaw &&
                    UnitJudgment == null &&
                    SpellManager.HasSpell("Long Arm of the Law"))
                {
                    UnitJudgment = NearbyUnFriendlyUnits.OrderByDescending(HealWeight).FirstOrDefault(
                        unit => BasicCheck(unit) &&
                                (InBattleground || InArena) &&
                                IsMoving(Me) &&
                                (MeHasAura("Hand of Freedom") || Me.MovementInfo.RunSpeed < 4) &&
                                !InvulnerableSpell(unit) &&
                                Attackable(unit, 30 + _bonusJudgementRange));
                }
                //also support  [Selfless Healer]
                if (THSettings.Instance.SelflessHealer &&
                    UnitJudgment == null &&
                    SpellManager.HasSpell("Selfless Healer"))
                {
                    UnitJudgment = NearbyUnFriendlyUnits.OrderByDescending(HealWeight).FirstOrDefault(
                        unit => BasicCheck(unit) &&
                                unit.GotTarget &&
                                IsMoving(Me) &&
                                !InvulnerableSpell(unit) &&
                                Attackable(unit, 30 + _bonusJudgementRange));
                }
                return BasicCheck(UnitJudgment);
            }
        }

        private static Composite AttackRotationHolyInstantComp()
        {
            return new PrioritySelector(
                new Decorator(
                    ret =>
                    (THSettings.Instance.JudgmentHolyAttack ||
                     THSettings.Instance.JudgmentLongArmoftheLaw ||
                     THSettings.Instance.JudgmentBurdenofGuilt) &&
                    //S//SSpellManager.HasSpell("Judgment") &&
                    Me.ManaPercent >= THSettings.Instance.ManaforDPS &&
                    BasicCheck(UnitHeal) &&
                    HealWeightUnitHeal >= THSettings.Instance.PriorityHeal &&
                    GetUnitJudgment() &&
                    UnitJudgment.Distance < 30 + _bonusJudgementRange &&
                    CanCastCheck("Judgment"),
                    new Action(delegate
                        {
                            //Logging.Write(LogLevel.Diagnostic, "Judgment UnitJudgment");
                            CastSpell("Judgment", UnitJudgment);
                            UnitJudgment = null;
                        })),
                new Decorator(
                    ret =>
                    SpellManager.HasSpell("Word of Glory") &&
                    !SpellManager.HasSpell("Eternal Flame") &&
                    Me.ManaPercent >= THSettings.Instance.ManaforDPS &&
                    BasicCheck(UnitHeal) &&
                    HealWeightUnitHeal > THSettings.Instance.PriorityHeal &&
                    Attackable(UnitAttack, 40) &&
                    HasGlyph.Contains("41107") && //Glyph of Harsh Words
                    (PlayerHolyPower >= 3 ||
                     MeHasAura(" Divine Purpose")) &&
                    HealWeightUnitHeal > THSettings.Instance.WordofGloryHolyHP &&
                    !InvulnerableSpell(UnitAttack) &&
                    FacingOverride(UnitAttack) &&
                    CanCastCheck("Word of Glory"),
                    new Action(delegate
                        {
                            SafelyFacingTarget(UnitAttack);
                            //Logging.Write(LogLevel.Diagnostic, "Word of Glory UnitAttack");
                            CastSpell("Word of Glory", UnitAttack, "Glyph of Harsh Words");
                            UnitAttack = null;
                        })),
                new Decorator(
                    ret =>
                    THSettings.Instance.HolyShockOffensive &&
                    //S//SSpellManager.HasSpell("Holy Shock") &&
                    Me.ManaPercent >= THSettings.Instance.ManaforDPS &&
                    BasicCheck(UnitHeal) &&
                    HealWeightUnitHeal > THSettings.Instance.DoNotHealAbove &&
                    Attackable(UnitAttack, 40) &&
                    !InvulnerableSpell(UnitAttack) &&
                    FacingOverride(UnitAttack) &&
                    CanCastCheck("Holy Shock"),
                    new Action(delegate
                        {
                            SafelyFacingTarget(UnitAttack);
                            //Logging.Write(LogLevel.Diagnostic, "Holy Shock UnitAttack");
                            CastSpell("Holy Shock", UnitAttack);
                            //UnitAttack = null;
                        }))
                );
        }

        private static Composite AttackRotationHolyCastComp()
        {
            return new PrioritySelector(
                new Decorator(
                    ret =>
                    THSettings.Instance.Denounce &&
                    //S//SSpellManager.HasSpell("Denounce") &&
                    !IsMoving(Me) &&
                    BasicCheck(UnitHeal) &&
                    HealWeightUnitHeal > THSettings.Instance.PriorityHeal &&
                    Attackable(UnitAttack, 30) &&
                    (UnitAttack.IsPlayer || UnitAttack.HealthPercent < 30) &&
                    (Me.ManaPercent > THSettings.Instance.ManaforDPS ||
                     UnitAttack.HealthPercent < 30 ||
                     MeHasAura("Glyph of Denouce")) &&
                    !InvulnerableSpell(UnitAttack) &&
                    CanCastCheck("Denounce"),
                    new Action(delegate
                        {
                            WoWMovement.ConstantFace(UnitAttack.Guid);
                            CastSpell("Denounce", UnitAttack);
                            UnitAttack = null;
                        }))
                );
        }

        #endregion

        #region AutoFocus

        private static WoWUnit UnitBestFocus;

        private static bool GetBestFocus()
        {
            UnitBestFocus = null;

            UnitBestFocus = NearbyUnFriendlyPlayers.OrderByDescending(TalentSort).
                                                    ThenByDescending(unit => unit.HealthPercent).
                                                    FirstOrDefault(
                                                        unit =>
                                                        unit != null && unit.IsValid &&
                                                            //Me.CurrentTarget != null &&
                                                        unit != Me.CurrentTarget &&
                                                        AttackableNoLoS(unit, 50));

            return BasicCheck(UnitBestFocus);
        }

        private static DateTime LastAutoFocus;

        private static Composite AutoSetFocus()
        {
            return new Action(delegate
            {
                //if (!THSettings.Instance.AutoSetFocus || LastAutoFocus > DateTime.Now)
                if (LastAutoFocus > DateTime.Now)
                {
                    return RunStatus.Failure;
                }


                if (Me.CurrentTarget != null &&
                    Me.FocusedUnit == null &&
                    GetBestFocus())
                {
                    //OriginalTarget = Me.CurrentTarget;
                    UnitBestFocus.Target();
                    Thread.Sleep(10);
                    Lua.DoString("RunMacroText('/focus');");
                    Me.SetFocus(UnitBestFocus);
                    Thread.Sleep(10);
                    Me.TargetLastTarget();
                    Logging.Write("Set Focus: " + SafeName(UnitBestFocus));
                    LastAutoFocus = DateTime.Now + TimeSpan.FromMilliseconds(2000);
                    return RunStatus.Failure;
                }

                if (UseSpecialization != 3 &&
                    Me.CurrentTarget != null &&
                    Me.FocusedUnit != null &&
                    (Me.CurrentTarget == Me.FocusedUnit ||
                     !AttackableNoCCLoS(Me.FocusedUnit, 60) ||
                     TalentSort(Me.FocusedUnit) < 4 &&
                     GetBestFocus() &&
                     TalentSort(UnitBestFocus) == 4))
                {
                    Logging.Write("Clear Focus");
                    //Logging.Write("Clear Focus: Focus = Target " +
                    //              "Target: " + SafeName(Me.CurrentTarget) +
                    //              " - Focus: " + SafeName(Me.FocusedUnit));
                    Lua.DoString("RunMacroText('/clearfocus');");
                    Me.SetFocus(0);
                    LastAutoFocus = DateTime.Now + TimeSpan.FromMilliseconds(1000);
                    return RunStatus.Failure;
                }
                return RunStatus.Failure;
            });
        }

        #endregion

        #region AutoTarget

        private static DateTime LastAutoTarget;

        private static Composite AutoTargetMelee()
        {
            return new Action(delegate
                {
                    if (!THSettings.Instance.AutoTarget ||
                        LastAutoTarget > DateTime.Now)
                    {
                        return RunStatus.Failure;
                    }

                    if (BasicCheck(Me.CurrentTarget) &&
                        !CurrentTargetAttackableNoLoS(50) &&
                        GetBestTarget() &&
                        Me.CurrentTarget != UnitBestTarget)
                    {
                        UnitBestTarget.Target();
                        Logging.Write(LogLevel.Diagnostic, "Switch to Best Unit");
                        LastAutoTarget = DateTime.Now + TimeSpan.FromMilliseconds(1000);
                        return RunStatus.Failure;
                    }

                    if (!BasicCheck(Me.CurrentTarget) &&
                        GetBestTarget())
                    {
                        UnitBestTarget.Target();
                        Logging.Write(LogLevel.Diagnostic, "Target  Best Unit");
                        LastAutoTarget = DateTime.Now + TimeSpan.FromMilliseconds(1000);
                        return RunStatus.Failure;
                    }
                    LastAutoTarget = DateTime.Now + TimeSpan.FromMilliseconds(1000);
                    return RunStatus.Failure;
                });
        }

        private static Composite AutoTargetRange()
        {
            return new Action(delegate
                {
                    if (!THSettings.Instance.AutoTarget ||
                        LastAutoTarget > DateTime.Now)
                    {
                        return RunStatus.Failure;
                    }

                    if (InArena || InBattleground)
                    {
                        if (BasicCheck(Me.CurrentTarget) &&
                            !CurrentTargetAttackableNoLoS(50) &&
                            GetBestTarget() &&
                            Me.CurrentTarget != UnitBestTarget)
                        {
                            UnitBestTarget.Target();
                            Logging.Write(LogLevel.Diagnostic, "Switch to Best Unit");
                            LastAutoTarget = DateTime.Now + TimeSpan.FromMilliseconds(1000);
                            return RunStatus.Failure;
                        }

                        if (!BasicCheck(Me.CurrentTarget) &&
                            GetBestTarget())
                        {
                            UnitBestTarget.Target();
                            Logging.Write(LogLevel.Diagnostic, "Target  Best Unit");
                            LastAutoTarget = DateTime.Now + TimeSpan.FromMilliseconds(1000);
                            return RunStatus.Failure;
                        }
                    }
                    else
                    {
                        if (GetBestTargetRange() &&
                            Me.CurrentTarget != UnitBestTarget)
                        {
                            UnitBestTarget.Target();
                            Logging.Write(LogLevel.Diagnostic, "Switch to Best Unit Ele");
                            LastAutoTarget = DateTime.Now + TimeSpan.FromMilliseconds(1000);
                            return RunStatus.Failure;
                        }
                    }

                    LastAutoTarget = DateTime.Now + TimeSpan.FromMilliseconds(1000);
                    return RunStatus.Failure;
                });
        }

       private static Composite AutoTarget()
        {
            return new Action(delegate
                {
                    if (!THSettings.Instance.AutoTarget ||
                        LastAutoTarget > DateTime.Now)
                    {
                        return RunStatus.Failure;
                    }

                    if (BasicCheck(Me.CurrentTarget) &&
                        !CurrentTargetAttackableNoLoS(50) &&
                        GetBestTarget() &&
                        Me.CurrentTarget != UnitBestTarget)
                    {
                        UnitBestTarget.Target();
                        Logging.Write(LogLevel.Diagnostic, "Switch to Best Unit");
                        LastAutoTarget = DateTime.Now + TimeSpan.FromMilliseconds(1000);
                        return RunStatus.Failure;
                    }

                    if (!BasicCheck(Me.CurrentTarget) &&
                        GetBestTarget())
                    {
                        UnitBestTarget.Target();
                        Logging.Write(LogLevel.Diagnostic, "Target  Best Unit");
                        LastAutoTarget = DateTime.Now + TimeSpan.FromMilliseconds(1000);
                        return RunStatus.Failure;
                    }
                    LastAutoTarget = DateTime.Now + TimeSpan.FromMilliseconds(1000);
                    return RunStatus.Failure;
                });
        }

        private static Composite AutoTargetProt()
        {
            return new Action(delegate
                {
                    if (!THSettings.Instance.AutoTarget ||
                        LastAutoTarget > DateTime.Now)
                    {
                        return RunStatus.Failure;
                    }

                    if (InArena || InBattleground)
                    {
                        if (BasicCheck(Me.CurrentTarget) &&
                            !CurrentTargetAttackableNoLoS(50) &&
                            GetBestTarget() &&
                            Me.CurrentTarget != UnitBestTarget)
                        {
                            UnitBestTarget.Target();
                            Logging.Write(LogLevel.Diagnostic, "Switch to Best Unit");
                            LastAutoTarget = DateTime.Now + TimeSpan.FromMilliseconds(1000);
                            return RunStatus.Failure;
                        }

                        if (!BasicCheck(Me.CurrentTarget) &&
                            GetBestTarget())
                        {
                            UnitBestTarget.Target();
                            Logging.Write(LogLevel.Diagnostic, "Target  Best Unit");
                            LastAutoTarget = DateTime.Now + TimeSpan.FromMilliseconds(1000);
                            return RunStatus.Failure;
                        }
                    }
                    else
                    {
                        if (GetBestTargetProt() &&
                            Me.CurrentTarget != UnitBestTarget)
                        {
                            UnitBestTarget.Target();
                            Logging.Write(LogLevel.Diagnostic, "Switch to Best Unit Prot");
                            LastAutoTarget = DateTime.Now + TimeSpan.FromMilliseconds(1000);
                            return RunStatus.Failure;
                        }
                    }

                    LastAutoTarget = DateTime.Now + TimeSpan.FromMilliseconds(1000);
                    return RunStatus.Failure;
                });
        }

        #endregion

        #region Avenger's Shield

        private static Composite AvengersShield()
        {
            return new Decorator(
                ret =>
                THSettings.Instance.AvengersShield &&
                //S//SSpellManager.HasSpell("Avenger's Shield") &&
                ////!Me.Mounted &&
                CurrentTargetAttackable(30) &&
                FacingOverride(Me.CurrentTarget) &&
                !InvulnerableSpell(Me.CurrentTarget) &&
                CanCastCheck("Avenger's Shield"),
                new Action(delegate
                    {
                        SafelyFacingTarget(Me.CurrentTarget);
                        CastSpell("Avenger's Shield", Me.CurrentTarget);
                    })
                );
        }

        #endregion

        #region AvengersShieldInterrupt

        private static WoWUnit UnitAvengersShieldInterrupt;

        private static bool GetUnitAvengersShieldInterrupt()
        {
            UnitAvengersShieldInterrupt = null;

            ////using (StyxWoW.Memory.AcquireFrame())
            {
                if (InBattleground || InArena)
                {
                    UnitAvengersShieldInterrupt = NearbyUnFriendlyPlayers.FirstOrDefault(
                        unit =>
                        BasicCheck(unit) &&
                        (THSettings.Instance.InterruptAll ||
                         THSettings.Instance.InterruptTarget &&
                         Me.CurrentTarget != null &&
                         unit == Me.CurrentTarget ||
                         THSettings.Instance.InterruptFocus &&
                         Me.FocusedUnit != null &&
                         unit == Me.FocusedUnit) &&
                        FacingOverride(unit) &&
                        InterruptCheck(unit, THSettings.Instance.RebukeMs + MyLatency, false) &&
                        Attackable(unit, 30));
                }
                else
                {
                    UnitAvengersShieldInterrupt = NearbyUnFriendlyUnits.FirstOrDefault(
                        unit =>
                        BasicCheck(unit) &&
                        (THSettings.Instance.InterruptAll ||
                         THSettings.Instance.InterruptTarget &&
                         Me.CurrentTarget != null &&
                         unit == Me.CurrentTarget ||
                         THSettings.Instance.InterruptFocus &&
                         Me.FocusedUnit != null &&
                         unit == Me.FocusedUnit) &&
                        FacingOverride(unit) &&
                        FarFriendlyUnits.Contains(unit.CurrentTarget) &&
                        (unit.CurrentTarget == Me ||
                         !unit.CurrentTarget.HasAura("Vengeance")) &&
                        InterruptCheck(unit, THSettings.Instance.RebukeMs + MyLatency, false) &&
                        Attackable(unit, 30));
                }
            }

            return BasicCheck(UnitAvengersShieldInterrupt);
        }

        private void AvengersShieldInterruptVoid()
        {
            if (THSettings.Instance.HammerofJusticeInterrupt &&
                LastInterrupt < DateTime.Now &&
                //S//SSpellManager.HasSpell("Avenger's Shield") &&
                GetUnitAvengersShieldInterrupt() &&
                CanCastCheck("Avenger's Shield"))
            {
                if (Me.IsCasting || Me.IsChanneling)
                {
                    SpellManager.StopCasting();
                }
                SafelyFacingTarget(UnitAvengersShieldInterrupt);

                while (UnitAvengersShieldInterrupt.CurrentCastTimeLeft.TotalMilliseconds >
                       THSettings.Instance.RebukeMs + MyLatency)
                {
                    Logging.Write("Waiting for AvengerShieldInterrupt");
                }

                if (UnitAvengersShieldInterrupt.IsCasting || UnitAvengersShieldInterrupt.IsChanneling)
                {
                    CastSpell("Avenger's Shield", UnitAvengersShieldInterrupt,
                              "AvengersShieldInterrupt");
                    LastInterrupt = DateTime.Now + TimeSpan.FromMilliseconds(1500) + TimeSpan.FromMilliseconds(1500);
                }
            }
        }

        #endregion

        #region Avenger's Shield Lose Threat

        private static Composite AvengersShieldLoseThreat()
        {
            return new Decorator(
                ret =>
                THSettings.Instance.AvengersShieldLowestThreat &&
                //S//SSpellManager.HasSpell("Avenger's Shield") &&
                Me.Combat &&
                GetUnitReckoningProtection() &&
                CanCastCheck("Avenger's Shield"),
                new Action(
                    ret =>
                        {
                            SafelyFacingTarget(UnitReckoningProtection);
                            CastSpell("Avenger's Shield", UnitReckoningProtection, "AvengersShieldLoseThreat");
                        })
                );
        }

        #endregion

        #region AvengersShieldProtection

        private static WoWUnit UnitAvengersShielLowestThreat;

        private static bool GetAvengersShieldLowestThreatUnit()
        {
            UnitAvengersShielLowestThreat = null;

            //using (StyxWoW.Memory.AcquireFrame())
            {
                UnitAvengersShielLowestThreat =
                    NearbyUnFriendlyUnits.OrderBy(unit => unit.ThreatInfo.RawPercent).FirstOrDefault(
                        unit => BasicCheck(unit) &&
                                (InDungeon || InRaid) &&
                                unit.IsValid &&
                                Me.Combat &&
                                unit.Combat &&
                                FacingOverride(unit) &&
                                FarFriendlyUnits.Contains(unit.CurrentTarget) &&
                                !unit.CurrentTarget.HasAura("Vengeance") &&
                                GetDistance(unit) < 30 &&
                                InLineOfSpellSightCheck(unit));

                return BasicCheck(UnitAvengersShielLowestThreat);
            }
        }

        private static Composite AvengersShieldLowestThreatUnit()
        {
            return new Decorator(
                ret =>
                THSettings.Instance.AvengersShieldLowestThreat &&
                //S//SSpellManager.HasSpell("Avenger's Shield") &&
                ////!Me.Mounted &&
                GetAvengersShieldLowestThreatUnit() &&
                CanCastCheck("Avenger's Shield"),
                new Action(delegate
                    {
                        SafelyFacingTarget(UnitAvengersShielLowestThreat);
                        CastSpell("Avenger's Shield", UnitAvengersShielLowestThreat, "AvengersShieldLowestThreat");
                    })
                );
        }

        private static Composite AvengersShieldGrandCrusader()
        {
            return new Decorator(
                ret =>
                THSettings.Instance.AvengersShield &&
                //S//SSpellManager.HasSpell("Avenger's Shield") &&
                ////!Me.Mounted &&
                CurrentTargetAttackable(30) &&
                MeHasAura("Grand Crusader") &&
                CanCastCheck("Avenger's Shield"),
                new Action(delegate
                    {
                        SafelyFacingTarget(Me.CurrentTarget);
                        CastSpell("Avenger's Shield", Me.CurrentTarget, "AvengersShieldGrandCrusader");
                    })
                );
        }

        #endregion

        #region AvengingWrath

        private static double CountUnitHealthBelow(int HealthPercent)
        {
            return NearbyFriendlyPlayers.Count(
                unit =>
                BasicCheck(unit) &&
                HealWeight(unit) <= HealthPercent);
        }

        private static Composite AvengingWrath()
        {
            return new Decorator(
                ret =>
                THSettings.Instance.AvengingWrathHoly &&
                LastBurstCalled < DateTime.Now &&
                //S//SSpellManager.HasSpell("Avenging Wrath") &&
                HealWeightUnitHeal <= THSettings.Instance.AvengingWrathHolyHP &&
                UnitHeal.Combat &&
                !UnitHeal.IsPet &&
                (THSettings.Instance.AvengingWrathHolyNumber <= 1 ||
                 CountUnitHealthBelow(THSettings.Instance.AvengingWrathHolyHP) >=
                 THSettings.Instance.AvengingWrathHolyNumber) &&
                !MeHasAura("Divine Shield") &&
                Healable(UnitHeal) &&
                CanCastCheck("Avenging Wrath", true),
                new Action(delegate
                    {
                        if (Me.IsCasting && !IsHealing())
                        {
                            SpellManager.StopCasting();
                        }
                        LastBurstCalled = DateTime.Now +
                                          TimeSpan.FromSeconds(THSettings.Instance.BurstDelay);
                        CastSpell("Avenging Wrath", Me);
                        return RunStatus.Failure;
                    }));
        }

        #endregion

        #region AvengingWrathBurstRet

        private static Composite AvengingWrathBurstRet()
        {
            return new Decorator(
                ret =>
                THSettings.Instance.Burst &&
                THSettings.Instance.AvengingWrath &&
                //S//SSpellManager.HasSpell("Avenging Wrath") &&
                //S//SSpellManager.HasSpell("Guardian of Ancient Kings") &&
                ////!Me.Mounted &&
                (CurrentTargetAttackable(15) ||
                 CurrentTargetAttackable(30) &&
                 //S//SSpellManager.HasSpell("Sanctified Wrath")) &&
                !Me.CurrentTarget.IsFlying &&
                GetSpellCooldown("Guardian of Ancient Kings").TotalSeconds < 294 &&
                GetSpellCooldown("Guardian of Ancient Kings").TotalSeconds > 0 &&
                CanCastCheck("Avenging Wrath", true),
                new Action(delegate
                    {
                        CastSpell("Avenging Wrath", Me);
                        return RunStatus.Failure;
                    })
                );
        }

        #endregion

        #region Beacon of Light

        private static WoWUnit UnitBeaconSecond;

        private static void BeaconHealSecondUnit(WoWUnit target)
        {
            if (THSettings.Instance.EternalFlameBlanketHolyPower > 0)
            {
                return;
            }

            if (!//S//SSpellManager.HasSpell("Beacon of Light"))
            {
                //Logging.Write(LogLevel.Diagnostic, "BeaconHealSecondUnit: No Spell Beacon of Light");
                return;
            }

            if (!THSettings.Instance.BeaconofLight)
            {
                //Logging.Write(LogLevel.Diagnostic, "BeaconHealSecondUnit: BeaconofLight Unchecked");
                return;
            }

            if (target == null)
            {
                return;
            }

            if (!HasGlyph.Contains("63218")) //"Glyph of Beacon of Light")
            {
                //Logging.Write(LogLevel.Diagnostic, "BeaconHealSecondUnit: No Glyph of Beacon of Light");
                return;
            }

            UnitBeaconSecond = null;

            UnitBeaconSecond = FarFriendlyPlayers.OrderBy(HealWeight).FirstOrDefault(
                unit =>
                BasicCheck(unit) &&
                unit != target &&
                Healable(unit, 60));

            if (////!Me.Mounted &&
                BasicCheck(UnitBeaconSecond) &&
                !MyAura("Beacon of Light", UnitBeaconSecond) &&
                Healable(UnitBeaconSecond, 60) &&
                CanCastCheck("Beacon of Light"))
            {
                CastSpell("Beacon of Light", UnitBeaconSecond, "BeaconHealSecondUnit");
                //Logging.Write(DateTime.Now.ToString("ss:fff") + " HP: " +
                //              Math.Round(HealWeightMe) + "% Mana: " +
                //              Math.Round(Me.ManaPercent) +
                //              "% Beacon of Light to Heal Second Unit " +
                //              UnitBeaconSecond.Class + " " +
                //              Math.Round(UnitBeaconSecond.Distance) + "y " +
                //              Math.Round(UnitBeaconSecond.HealthPercent) + "% hp");
            }
            else if (////!Me.Mounted &&
                     UnitBeaconSecond == null &&
                     !MyAura("Beacon of Light", Me) &&
                     Healable(Me))
            {
                SpellManager.Cast("Beacon of Light", Me);
            }
        }

        private static WoWUnit UnitBeaconFirst;

        private static Composite BeaconHealFirstUnit()
        {
            return new Decorator(
                ret =>
                THSettings.Instance.EternalFlameBlanketHolyPower > 0 &&
                THSettings.Instance.BeaconofLight &&
                //S//SSpellManager.HasSpell("Beacon of Light") &&
                ////!Me.Mounted &&
                GetUnitBeaconFirst() &&
                !MyAura("Beacon of Light", UnitBeaconFirst) &&
                CanCastCheck("Beacon of Light", true),
                new Action(delegate
                    {
                        CastSpell("Beacon of Light", UnitBeaconFirst, "BeaconHealFirstUnit");
                        return RunStatus.Failure;
                    })
                );
        }

        private static bool GetUnitBeaconFirst()
        {
            UnitBeaconFirst = null;

            //using (StyxWoW.Memory.AcquireFrame())
            {
                UnitBeaconFirst = FarFriendlyPlayers.OrderBy(HealWeight).FirstOrDefault(
                    unit =>
                    BasicCheck(unit) &&
                    Healable(unit, 60));
            }

            if (UnitBeaconFirst == null && !MyAura("Beacon of Light", Me))
            {
                UnitBeaconFirst = Me;
            }

            return BasicCheck(UnitBeaconFirst);
        }

        private static void BeaconBuildHolyPower(WoWUnit target)
        {
            if (!//S//SSpellManager.HasSpell("Beacon of Light"))
            {
                //Logging.Write(LogLevel.Diagnostic, "BeaconBuildHolyPower: No Spell Beacon of Light");
                return;
            }

            if (!THSettings.Instance.BeaconofLight)
            {
                //Logging.Write(LogLevel.Diagnostic, "BeaconBuildHolyPower: BeaconofLight Unchecked");
                return;
            }

            if (!HasGlyph.Contains("63218")) //"Glyph of Beacon of Light")
            {
                //Logging.Write(LogLevel.Diagnostic, "BeaconBuildHolyPower: No Glyph of Beacon of Light");
                return;
            }

            if (!MyAura("Beacon of Light", target) &&
                Healable(target, 60) &&
                CanCastCheck("Beacon of Light"))
            {
                {
                    CastSpell("Beacon of Light", target, "BeaconBuildHolyPower");
                    //SpellManager.Cast("Beacon of Light", u);
                    //Logging.Write(DateTime.Now.ToString("ss:fff") + " HP: " +
                    //              Math.Round(HealWeightMe) + "% Mana: " +
                    //              Math.Round(Me.ManaPercent) +
                    //              "% Beacon of Light to build Holy Power " +
                    //              u.Class +
                    //              " " + Math.Round(u.Distance) + "y " +
                    //              Math.Round(u.HealthPercent) + "% hp");
                }
            }
        }

        #endregion

        #region BlindingLight

        private static WoWUnit UnitBlindingLight;

        private static bool GetUnitBlindingLight()
        {
            UnitBlindingLight = null;

            if (InBattleground || InArena)
            {
                UnitBlindingLight = NearbyUnFriendlyPlayers.FirstOrDefault(
                    unit => BasicCheck(unit) &&
                            (THSettings.Instance.InterruptAll ||
                             THSettings.Instance.InterruptTarget &&
                             Me.CurrentTarget != null &&
                             unit == Me.CurrentTarget ||
                             THSettings.Instance.InterruptFocus &&
                             Me.FocusedUnit != null &&
                             unit == Me.FocusedUnit) &&
                            //DebuffDot(unit) &&
                            InterruptCheck(unit, THSettings.Instance.BlindingLightInterruptMs + MyLatency,
                                           false) &&
                            Attackable(unit, 5));
            }
                //PvE Search
            else
            {
                UnitBlindingLight = NearbyUnFriendlyUnits.FirstOrDefault(
                    unit => BasicCheck(unit) &&
                            unit.Combat &&
                            //DebuffDot(unit) &&
                            (THSettings.Instance.InterruptAll ||
                             THSettings.Instance.InterruptTarget &&
                             Me.CurrentTarget != null &&
                             unit == Me.CurrentTarget ||
                             THSettings.Instance.InterruptFocus &&
                             Me.FocusedUnit != null &&
                             unit == Me.FocusedUnit) &&
                            FarFriendlyUnits.Contains(unit.CurrentTarget) &&
                            InterruptCheck(unit, THSettings.Instance.BlindingLightInterruptMs + MyLatency,
                                           false) &&
                            Attackable(unit, 5));
            }

            return BasicCheck(UnitBlindingLight);
        }

        private void BlindingLightVoid()
        {
            if (THSettings.Instance.BlindingLightInterrupt &&
                LastInterrupt < DateTime.Now &&
                //S//SSpellManager.HasSpell("Blinding Light") &&
                BasicCheck(UnitHeal) &&
                HealWeightUnitHeal > THSettings.Instance.UrgentHeal &&
                GetUnitBlindingLight() &&
                CanCastCheck("Blinding Light"))
            {
                if (Me.IsCasting || Me.IsChanneling)
                {
                    SpellManager.StopCasting();
                }

                while (UnitBlindingLight.CurrentCastTimeLeft.TotalMilliseconds >
                       THSettings.Instance.BlindingLightInterruptMs + MyLatency)
                {
                    Logging.Write("Waiting for Blinding Light");
                }

                if (UnitBlindingLight.IsCasting || UnitBlindingLight.IsChanneling)
                {
                    CastSpell("Blinding Light", Me, "BlindingLight");
                    LastInterrupt = DateTime.Now + TimeSpan.FromMilliseconds(1500);
                }
            }
        }

        #endregion

        #region Buff

        private static Composite BuffRotation()
        {
            return new PrioritySelector(
                new Decorator(
                    ret =>
                    THSettings.Instance.AutoBuff &&
                    THSettings.Instance.PreferMight &&
                    //S//SSpellManager.HasSpell("Blessing of Might") &&
                    ////!Me.Mounted &&
                    BasicCheck(UnitHeal) &&
                    UnitHeal.IsPlayer &&
                    //(UnitHeal == Me || InArena) &&
                    !HasOneAura(UnitHeal,
                                new HashSet<string>
                                    {
                                        "Blessing of Might",
                                        "Grace of Air",
                                        "Roar of Courage",
                                        "Spirit Beast Blessing",
                                    }) &&
                    //!UnitHeal.HasAura("Blessing of Might") &&
                    //!UnitHeal.HasAura("Grace of Air") &&
                    //!UnitHeal.HasAura("Roar of Courage") &&
                    //!UnitHeal.HasAura("Spirit Beast Blessing") &&
                    CanCastCheck("Blessing of Might"),
                    new Action(delegate { CastSpell("Blessing of Might", Me); })),
                new Decorator(
                    ret =>
                    THSettings.Instance.AutoBuff &&
                    THSettings.Instance.PreferMight &&
                    //S//SSpellManager.HasSpell("Blessing of Kings") &&
                    ////!Me.Mounted &&
                    BasicCheck(UnitHeal) &&
                    UnitHeal.IsPlayer &&
                    HasOneAura(UnitHeal,
                               new HashSet<string>
                                   {
                                       "Blessing of Might",
                                       "Grace of Air",
                                       "Roar of Courage",
                                       "Spirit Beast Blessing",
                                   }) &&
                    !MyAura("Blessing of Might", UnitHeal) &&
                    !HasOneAura(UnitHeal,
                                new HashSet<string>
                                    {
                                        "Spirit Beast Blessing",
                                        "Blessing of Kings",
                                        "Embrace of the Shale Spider",
                                        "Legacy of the Emperor",
                                        "Mark of the Wild",
                                    }) &&
                    //(UnitHeal == Me || InArena) &&
                    //(UnitHeal.HasAura("Blessing of Might") && !MyAura("Blessing of Might", UnitHeal) ||
                    // UnitHeal.HasAura("Grace of Air") ||
                    // UnitHeal.HasAura("Roar of Courage") ||
                    // UnitHeal.HasAura("Spirit Beast Blessing")) &&
                    //!UnitHeal.HasAura("Blessing of Kings") &&
                    //!UnitHeal.HasAura("Embrace of the Shale Spider") &&
                    //!UnitHeal.HasAura("Legacy of the Emperor") &&
                    //!UnitHeal.HasAura("Mark of the Wild") &&
                    CanCastCheck("Blessing of Kings"),
                    new Action(delegate { CastSpell("Blessing of Kings", Me); AuraCacheUpdate(Me, true); })),
                new Decorator(
                    ret =>
                    THSettings.Instance.AutoBuff &&
                    THSettings.Instance.PreferKings &&
                    //S//SSpellManager.HasSpell("Blessing of Kings") &&
                    ////!Me.Mounted &&
                    BasicCheck(UnitHeal) &&
                    UnitHeal.IsPlayer &&
                    !HasOneAura(UnitHeal,
                                new HashSet<string>
                                    {
                                        "Spirit Beast Blessing",
                                        "Blessing of Kings",
                                        "Embrace of the Shale Spider",
                                        "Legacy of the Emperor",
                                        "Mark of the Wild",
                                    }) &&
                    //(UnitHeal == Me || InArena) &&
                    //!UnitHeal.HasAura("Blessing of Kings") &&
                    //!UnitHeal.HasAura("Legacy of the Emperor") &&
                    //!UnitHeal.HasAura("Mark of the Wild") &&
                    //!UnitHeal.HasAura("Embrace of the Shale Spider") &&
                    CanCastCheck("Blessing of Kings"),
                    new Action(delegate { CastSpell("Blessing of Kings", Me); AuraCacheUpdate(Me, true); })),
                new Decorator(
                    ret =>
                    THSettings.Instance.AutoBuff &&
                    THSettings.Instance.PreferKings &&
                    //S//SSpellManager.HasSpell("Blessing of Might") &&
                    ////!Me.Mounted &&
                    BasicCheck(UnitHeal) &&
                    UnitHeal.IsPlayer &&
                    HasOneAura(UnitHeal,
                               new HashSet<string>
                                   {
                                       "Spirit Beast Blessing",
                                       "Blessing of Kings",
                                       "Embrace of the Shale Spider",
                                       "Legacy of the Emperor",
                                       "Mark of the Wild",
                                   }) &&
                    !MyAura("Blessing of Kings", UnitHeal) &&
                    !HasOneAura(UnitHeal,
                                new HashSet<string>
                                    {
                                        "Blessing of Might",
                                        "Grace of Air",
                                        "Roar of Courage",
                                        "Spirit Beast Blessing",
                                    }) &&
                    //(UnitHeal == Me || InArena) &&
                    //(UnitHeal.HasAura("Blessing of Kings") && !MyAura("Blessing of Kings", UnitHeal) ||
                    // UnitHeal.HasAura("Legacy of the Emperor") ||
                    // UnitHeal.HasAura("Embrace of the Shale Spider") ||
                    // UnitHeal.HasAura("Mark of the Wild")) &&
                    //!UnitHeal.HasAura("Blessing of Might") &&
                    //!UnitHeal.HasAura("Grace of Air") &&
                    //!UnitHeal.HasAura("Roar of Courage") &&
                    //!UnitHeal.HasAura("Spirit Beast Blessing") &&
                    CanCastCheck("Blessing of Might"),
                    new Action(delegate { CastSpell("Blessing of Might", Me); AuraCacheUpdate(Me, true); }))
                )
                ;
        }

        #endregion

        #region BubbleFlashofLightRet

        private static Composite BubbleFlashofLightRet()
        {
            return new Decorator(
                ret =>
                //S//SSpellManager.HasSpell("Flash of Light") &&
                ////!Me.Mounted &&
                Me.CurrentMana > Me.MaxMana*0.378 &&
                !InDungeon &&
                !InRaid &&
                !IsMoving(Me) &&
                HasOneAura(Me,
                           new HashSet<string>
                               {
                                   "Divine Shield",
                                   "Devotion Aura",
                                   "Hand of Protection",
                               }) &&
                //(MeHasAura("Divine Shield") ||
                // MeHasAura("Devotion Aura") ||
                // MeHasAura("Hand of Protection")) &&
                HealWeightMe < THSettings.Instance.DoNotHealAbove &&
                CanCastCheck("Flash of Light"),
                new Action(delegate
                    {
                        if (IsMoving(Me))
                        {
                            Navigator.PlayerMover.MoveStop();
                            WoWMovement.MoveStop();
                        }
                        //Logging.Write(LogLevel.Diagnostic, "BubbleFlashofLightRet");
                        DoNotMove = DateTime.Now + TimeSpan.FromSeconds(1);
                        CastSpell("Flash of Light", Me);
                        if (DoNotMove < DateTime.Now)
                        {
                            return RunStatus.Running;
                        }
                        return RunStatus.Success;
                    })
                );
        }

        #endregion

        #region BubbleFlashofLightRet

        private static Composite CancelBubbleProtection()
        {
            return new Decorator(
                ret =>
                THSettings.Instance.AutoCancelBubble &&
                ////!Me.Mounted &&
                HasOneAura(Me,
                           new HashSet<string>
                               {
                                   "Divine Shield",
                                   "Hand of Protection",
                               }) &&
                //(MeHasAura("Divine Shield") ||
                // MeHasAura("Hand of Protection")) &&
                HealWeightMe >= THSettings.Instance.AutoCancelBubbleHP,
                new Action(delegate
                    {
                        CancelAura(642, Me);
                        CancelAura(1022, Me);
                        //Lua.DoString("RunMacroText('/cancelaura " + WoWSpell.FromId(642) + "');");
                        //Lua.DoString("RunMacroText('/cancelaura " + WoWSpell.FromId(1022) + "');");
                        //Lua.DoString("CancelUnitBuff(\"Player\",\"Divine Shield\")");
                        //Lua.DoString("CancelUnitBuff(\"Player\",\"Hand of Protection\")");
                        AuraCacheUpdate(Me, true);
                        return RunStatus.Failure;
                    })
                );
        }

        #endregion

        #region CleanseFriendlyASAPComp

        private static WoWUnit PlayerFriendlyCleanseASAP;

        private static bool GetPlayerFriendlyCleanseASAP()
        {
            PlayerFriendlyCleanseASAP = null;

            if (!THSettings.Instance.CleanseASAP || !Me.Combat)
            {
                return false;
            }
            //using (StyxWoW.Memory.AcquireFrame())
            {
                PlayerFriendlyCleanseASAP = NearbyFriendlyPlayers.FirstOrDefault(
                    unit => BasicCheck(unit) &&
                            !DebuffDoNotCleanse(unit) &&
                            (DebuffCCleanseASAP(unit) ||
                             DebuffCCBreakonDamage(unit) &&
                             !DebuffDot(unit)) &&
                            Healable(unit));
            }

            return BasicCheck(PlayerFriendlyCleanseASAP);
        }

        private static Composite CleanseFriendlyASAPComp()
        {
            return new PrioritySelector(
                new Decorator(
                    ret =>
                    THSettings.Instance.CleanseASAP &&
                    //S//SSpellManager.HasSpell("Cleanse") &&
                    BasicCheck(UnitHeal) &&
                    HealWeightUnitHeal > THSettings.Instance.PriorityHeal &&
                    GetPlayerFriendlyCleanseASAP() &&
                    CanCastCheck("Cleanse"),
                    new Action(delegate
                        {
                            SpellManager.StopCasting();
                            CastSpell("Cleanse", PlayerFriendlyCleanseASAP, "CleanseFriendlyASAPComp");
                        }))
                )
                ;
        }

        #endregion

        #region CleanseFriendlyComp

        private static WoWUnit PlayerFriendlyCleanse;

        private static bool GetPlayerFriendlyCleanse()
        {
            PlayerFriendlyCleanse = null;

            if (THSettings.Instance.CleanseDebuffNumber == 0 || !Me.Combat)
            {
                return false;
            }
            //using (StyxWoW.Memory.AcquireFrame())
            {
                PlayerFriendlyCleanse = NearbyFriendlyPlayers.OrderByDescending(CountDebuff).FirstOrDefault(
                    unit => BasicCheck(unit) &&
                            !DebuffDoNotCleanse(unit) &&
                            CountDebuff(unit) >= THSettings.Instance.CleanseDebuffNumber &&
                            Healable(unit));
            }

            return BasicCheck(PlayerFriendlyCleanse);
        }

        private static Composite CleanseFriendlyComp()
        {
            return new PrioritySelector(
                new Decorator(
                    ret =>
                    THSettings.Instance.CleanseDebuff &&
                    //S//SSpellManager.HasSpell("Cleanse") &&
                    BasicCheck(UnitHeal) &&
                    HealWeightUnitHeal > THSettings.Instance.PriorityHeal &&
                    Me.ManaPercent > 30 &&
                    GetPlayerFriendlyCleanse() && PlayerFriendlyCleanse.IsValid &
                    CanCastCheck("Cleanse"),
                    new Action(delegate
                        {
                            SpellManager.StopCasting();
                            CastSpell("Cleanse", PlayerFriendlyCleanse, "CleanseFriendlyComp");
                        }))
                );
        }

        #endregion

        #region CleanseMe

        private static Composite CleanseMe()
        {
            return new PrioritySelector(
                new Decorator(
                    ret =>
                    THSettings.Instance.CleanseDebuff &&
                    //S//SSpellManager.HasSpell("Cleanse") &&
                    Me.ManaPercent > 30 &&
                    BasicCheck(UnitHeal) &&
                    HealWeightUnitHeal > THSettings.Instance.UrgentHeal &&
                    (DebuffRootCanCleanse(Me) ||
                     CountDebuff(Me) >= THSettings.Instance.CleanseDebuffNumber) &&
                    !DebuffDoNotCleanse(Me) &&
                    CanCastCheck("Cleanse"),
                    new Action(delegate
                        {
                            SpellManager.StopCasting();
                            CastSpell("Cleanse", Me, "CleanseMe");
                        }))
                );
        }

        #endregion

        #region Consecration

        private static Composite Consecration()
        {
            return new Decorator(
                ret =>
                THSettings.Instance.Consecration &&
                //S//SSpellManager.HasSpell("Consecration") &&
                ////!Me.Mounted &&
                Me.Combat &&
                Me.ManaPercent > 50 &&
                (CurrentTargetAttackable(10) ||
                 CountEnemyNeary(Me, 10) > 0) &&
                CanCastCheck("Consecration"),
                new Action(delegate
                    {
                        //Logging.Write("Consecration soon");
                        CastSpell("Consecration", Me, "Consecration");
                        if (HasGlyph.Contains("54928"))
                        {
                            LastClickRemoteLocation = DateTime.Now + TimeSpan.FromMilliseconds(300);
                            while (LastClickRemoteLocation > DateTime.Now)
                            {
                                SpellManager.ClickRemoteLocation(Me.Location);
                            }
                        }
                    })
                );
        }

        private static Composite ConsecrationAoE()
        {
            return new Decorator(
                ret =>
                THSettings.Instance.Consecration &&
                //S//SSpellManager.HasSpell("Consecration") &&
                ////!Me.Mounted &&
                Me.Combat &&
                Me.ManaPercent > 50 &&
                CountEnemyNeary(Me, 10) >= 4 &&
                CanCastCheck("Consecration"),
                new Action(delegate
                    {
                        //Logging.Write("Consecration soon");
                        CastSpell("Consecration", Me, "ConsecrationAoE");
                        if (HasGlyph.Contains("54928"))
                        {
                            LastClickRemoteLocation = DateTime.Now + TimeSpan.FromMilliseconds(300);
                            while (LastClickRemoteLocation > DateTime.Now)
                            {
                                SpellManager.ClickRemoteLocation(Me.Location);
                            }
                        }
                    })
                );
        }

        #endregion

        #region CrusaderStrikeRet

        private static Composite CrusaderStrikeRet()
        {
            return new Decorator(
                ret =>
                //S//SSpellManager.HasSpell("Crusader Strike") &&
                ////!Me.Mounted &&
                PlayerHolyPower < Me.MaxHolyPower &&
                !HasOneAura(Me,
                            new HashSet<string>
                                {
                                    "Divine Purposes",
                                    "Hand of Protection",
                                }) &&
                //!MeHasAura("Divine Purposes") &&
                //!MeHasAura("Hand of Protection") &&
                CurrentTargetAttackable(5) &&
                FacingOverride(Me.CurrentTarget) &&
                CanCastCheck("Crusader Strike"),
                new Action(delegate
                    {
                        //
                        SafelyFacingTarget(Me.CurrentTarget);
                        CastSpell("Crusader Strike", Me.CurrentTarget, "CrusaderStrikeRet");
                    })
                );
        }

        #endregion

        #region CrusaderStrikeProt

        private static Composite CrusaderStrikeProt()
        {
            return new Decorator(
                ret =>
                //S//SSpellManager.HasSpell("Crusader Strike") &&
                ////!Me.Mounted &&
                (!THSettings.Instance.ShieldofRighterous ||
                 PlayerHolyPower < Me.MaxHolyPower) &&
                !HasOneAura(Me,
                            new HashSet<string>
                                {
                                    "Divine Purposes",
                                    "Hand of Protection",
                                }) &&
                //!MeHasAura("Divine Purposes") &&
                //!MeHasAura("Hand of Protection") &&
                CurrentTargetAttackable(5) &&
                FacingOverride(Me.CurrentTarget) &&
                CanCastCheck("Crusader Strike"),
                new Action(delegate
                    {
                        //
                        SafelyFacingTarget(Me.CurrentTarget);
                        CastSpell("Crusader Strike", Me.CurrentTarget, "CrusaderStrikeProt");
                    })
                );
        }

        #endregion

        #region CrusaderStrikeHoly

        private static WoWUnit UnitCrusaderStrike;

        private static bool GetUnitCrusaderStrikeHoly()
        {
            //using (StyxWoW.Memory.AcquireFrame())
            {
                UnitCrusaderStrike = null;

                UnitCrusaderStrike = NearbyUnFriendlyUnits.FirstOrDefault(
                    unit => BasicCheck(unit) &&
                            FacingOverride(unit) &&
                            Attackable(unit, 5));

                return BasicCheck(UnitCrusaderStrike);
            }
        }

        private static Composite CrusaderStrikeHoly()
        {
            return new PrioritySelector(
                new Decorator(
                    ret =>
                    THSettings.Instance.CrusaderStrikeHoly &&
                    !MeHasAura("Hand of Protection") &&
                    Me.Combat &&
                    PlayerHolyPower < Me.MaxHolyPower &&
                    GetUnitCrusaderStrikeHoly() &&
                    Me.IsFacing(UnitCrusaderStrike) &&
                    CanCastCheck("Crusader Strike"),
                    new Action(delegate
                        {
                            SafelyFacingTarget(UnitCrusaderStrike);
                            CastSpell("Crusader Strike", UnitCrusaderStrike);
                        }))
                );
        }

        #endregion

        #region DevotionAura

        private static WoWUnit UnitDevotionAuraSilence;

        private static bool GetUnitDevotionAuraSilence()
        {
            UnitDevotionAuraSilence = null;
            UnitDevotionAuraSilence = NearbyFriendlyPlayers.FirstOrDefault(
                unit => BasicCheck(unit) &&
                        HealWeight(unit) <= THSettings.Instance.DevotionAuraSilenceHP &&
                        (THSettings.Instance.DevotionAuraSilenceAny ||
                         THSettings.Instance.DevotionAuraSilenceHealer &&
                         TalentSort(unit) == 4 ||
                         THSettings.Instance.DevotionAuraSilenceCaster &&
                         TalentSort(unit) == 3) &&
                        DebuffSilence(unit));

            return BasicCheck(UnitDevotionAuraSilence);
        }

        private static Composite DevotionAura()
        {
            return new PrioritySelector(
                new Decorator(
                    ret =>
                    THSettings.Instance.DevotionAura &&
                    //S//SSpellManager.HasSpell("Devotion Aura") &&
                    HealWeightMe <= THSettings.Instance.DevotionAuraHP &&
                    Me.Combat &&
                    !HasOneAura(Me,
                                new HashSet<string>
                                    {
                                        "Divine Shield",
                                        "Devotion Aura",
                                    }) &&
                    CanCastCheck("Devotion Aura", true),
                    new Action(delegate
                        {
                            CastSpell("Devotion Aura", Me, "DevotionAura");
                            return RunStatus.Failure;
                        })),
                new Decorator(
                    ret =>
                    THSettings.Instance.DevotionAuraSilence &&
                    //S//SSpellManager.HasSpell("Devotion Aura") &&
                    GetUnitDevotionAuraSilence() &&
                    CanCastCheck("Devotion Aura", true),
                    new Action(delegate
                        {
                            CastSpell("Devotion Aura", Me, "DevotionAuraSilence");
                            return RunStatus.Failure;
                        }))
                );
        }

        #endregion

        #region DivineLightBubble

        private static Composite DivineLightBubble()
        {
            return new Decorator(
                ret =>
                THSettings.Instance.DivineLight &&
                //S//SSpellManager.HasSpell("Divine Light") &&
                (InBattleground ||
                 InArena) &&
                HasOneAura(Me,
                           new HashSet<string>
                               {
                                   "Divine Shield",
                                   "Devotion Aura",
                                   "Hand of Protection",
                               }) &&
                !IsMoving(Me) &&
                HealWeightUnitHeal <= THSettings.Instance.DoNotHealAbove &&
                MeHasAura(54149) && //Infusion of Light
                Healable(UnitHeal) &&
                CanCastCheck("Divine Light"),
                new Action(delegate { CastSpell("Divine Light", UnitHeal, "DivineLightBubble"); }));
        }

        #endregion

        #region DivineProtection

        private static Composite DivineProtection()
        {
            return new Decorator(
                ret =>
                THSettings.Instance.DivineProtection &&
                //S//SSpellManager.HasSpell("Divine Protection") &&
                ////!Me.Mounted &&
                Me.Combat &&
                (HealWeightMe <= THSettings.Instance.DivineProtectionHP ||
                 MeHasAura("Deep Freeze")) &&
                !MeHasAura("Divine Shield") &&
                CanCastCheck("Divine Protection", true),
                new Action(delegate
                    {
                        CastSpell("Divine Protection", Me);
                        return RunStatus.Failure;
                    })
                );
        }

        #endregion

        #region DivineShield

        private static Composite DivineShield()
        {
            return new Decorator(
                ret =>
                THSettings.Instance.DivineShield &&
                //S//SSpellManager.HasSpell("Divine Shield") &&
                ////!Me.Mounted &&
                Me.Combat &&
                !HasOneAura(Me,
                            new HashSet<string>
                                {
                                    "Forbearance",
                                    "Alliance Flag",
                                    "Horde Flag",
                                    "Netherstorm Flag",
                                    "Orb of Power",
                                    "Ardent Defender",
                                }) &&
                HealWeightMe <= THSettings.Instance.DivineShieldHP &&
                CountEnemyTargettingUnit(Me, 40) > 0 &&
                CanCastCheck("Divine Shield"),
                new Action(delegate { CastSpell("Divine Shield", Me, "DivineShield"); }));
        }

        #endregion

        #region DivineStorm3HolyPower

        private static Composite DivineStorm3HolyPower()
        {
            return new Decorator(
                ret =>
                THSettings.Instance.DivineStorm &&
                //S//SSpellManager.HasSpell("Divine Storm") &&
                //!Me.Mounted &&
                !MeHasAura("Hand of Protection") &&
                //!InArena &&
                //!InBattleground &&
                MyAuraTimeLeft(84963, Me) > 7000 &&
                CurrentTargetAttackable(5) &&
                (PlayerHolyPower >= 3 ||
                 MeHasAura(90174)) &&
                CountEnemyNeary(Me, 8) >= THSettings.Instance.DivineStormUnit &&
                CanCastCheck("Divine Storm"),
                new Action(delegate
                    {
                        //
                        CastSpell("Divine Storm", Me.CurrentTarget);
                    })
                );
        }

        #endregion

        #region DivineStorm5HolyPower

        private static Composite DivineStorm5HolyPower()
        {
            return new Decorator(
                ret =>
                THSettings.Instance.DivineStorm &&
                //S//SSpellManager.HasSpell("Divine Storm") &&
                //!Me.Mounted &&
                !MeHasAura("Hand of Protection") &&
                !InArena &&
                !InBattleground &&
                CurrentTargetAttackable(5) &&
                (PlayerHolyPower >= Me.MaxHolyPower ||
                 MeHasAura(90174) ||
                 PlayerHolyPower >= 3 &&
                 MeHasAura("Holy Avenger")) &&
                CountEnemyNeary(Me, 8) >= THSettings.Instance.DivineStormUnit &&
                CanCastCheck("Divine Storm"),
                new Action(delegate
                    {
                        //
                        SafelyFacingTarget(Me.CurrentTarget);
                        CastSpell("Divine Storm", Me.CurrentTarget);
                    })
                );
        }

        #endregion

        #region DivineFavor

        private static Composite DivineFavor()
        {
            return new Decorator(
                ret =>
                THSettings.Instance.DivineFavor &&
                //SSpellManager.HasSpell("Divine Favor") &&
                LastBurstCalled < DateTime.Now &&
                HealWeightUnitHeal <= THSettings.Instance.DivineFavorHP &&
                UnitHeal.Combat &&
                !UnitHeal.IsPet &&
                (THSettings.Instance.DivineFavorNumber <= 1 ||
                 CountUnitHealthBelow(THSettings.Instance.DivineFavorHP) >=
                 THSettings.Instance.DivineFavorNumber) &&
                !MeHasAura("Divine Shield") &&
                Healable(UnitHeal) &&
                CanCastCheck("Divine Favor", true),
                new Action(delegate
                    {
                        if (Me.IsCasting && !IsHealing())
                        {
                            SpellManager.StopCasting();
                        }
                        LastBurstCalled = DateTime.Now +
                                          TimeSpan.FromSeconds(THSettings.Instance.BurstDelay);
                        CastSpell("Divine Favor", Me);
                        return RunStatus.Failure;
                    }));
        }

        #endregion

        #region DivineLight

        private static Composite DivineLight()
        {
            return new Decorator(
                ret =>
                THSettings.Instance.DivineLight &&
                //SSpellManager.HasSpell("Divine Light") &&
                !IsMoving(Me) &&
                HealWeightUnitHeal <= THSettings.Instance.DivineLightHP &&
                (Me.Combat || UnitHeal.Combat) &&
                !HoldonDivinePleaHP() &&
                !InArena &&
                !InBattleground &&
                Healable(UnitHeal) &&
                CanCastCheck("Divine Light"),
                new Action(delegate { CastSpell("Divine Light", UnitHeal, "DivineLight"); }));
        }

        #endregion

        #region DivineLight

        private static Composite DivineLightProc()
        {
            return new Decorator(
                ret =>
                THSettings.Instance.DivineLight &&
                //SSpellManager.HasSpell("Divine Light") &&
                Me.GetAuraById(54149) != null &&
                !IsMoving(Me) &&
                HealWeightUnitHeal <= THSettings.Instance.DivineLightHP &&
                (Me.Combat || UnitHeal.Combat) &&
                !HoldonDivinePleaHP() &&
                Healable(UnitHeal),
                //SSpellManager.HasSpell("Divine Light"),
                new Action(delegate { CastSpell("Divine Light", UnitHeal, "DivineLightProc"); }));
        }

        #endregion

        #region DivinePlea

        private static Composite DivinePlea()
        {
            return new Decorator(
                ret =>
                THSettings.Instance.DivinePlea &&
                //SSpellManager.HasSpell("Divine Plea") &&
                (!IsMoving(Me) && HasGlyph.Contains("63223") ||
                 !HasGlyph.Contains("63223")) &&
                //!Me.Mounted &&
                !HasOneAura(Me,
                            new HashSet<string>
                                {
                                    "Arena Preparation",
                                    "Preparation",
                                    "Holy Avenger",
                                    "Avenging Wrath",
                                    "Divine Favor",
                                }) &&
                (Me.ManaPercent <= THSettings.Instance.DivinePleaHP ||
                 UseSpecialization == 1 &&
                 Me.ManaPercent < 70 &&
                 InRaid &&
                 MeHasAura("Hymn of Hope") &&
                 !HasGlyph.Contains("63223")) &&
                (HealWeightUnitHeal > THSettings.Instance.UrgentHeal ||
                 Me.ManaPercent < 10) &&
                Healable(UnitHeal) &&
                CanCastCheck("Divine Plea"),
                new Action(delegate { CastSpell("Divine Plea", Me); }));
        }

        #endregion

        #region Emancipate

        private static Composite Emancipate()
        {
            return new Decorator(
                ret =>
                THSettings.Instance.Emancipate &&
                //SSpellManager.HasSpell("Emancipate") &&
                //!Me.Mounted &&
                CurrentTargetAttackable(60) &&
                GetDistance(Me.CurrentTarget) > 5 &&
                !MeHasAura("Hand of Freedom") &&
                DebuffRootorSnare(Me) &&
                (!THSettings.Instance.HandofFreedomMyself ||
                 !CanCastCheck("Hand of Freedom")) &&
                CanCastCheck("Emancipate"),
                new Action(delegate { CastSpell("Emancipate", Me, "Emancipate"); })
                );
        }

        #endregion

        #region EternalFlame

        private static Composite EternalFlame()
        {
            return new Decorator(
                ret =>
                THSettings.Instance.WordofGloryHoly &&
                //SSpellManager.HasSpell("Eternal Flame") &&
                //!Blacklist.Contains(UnitHeal.Guid, BlacklistFlags.All) &&
                (PlayerHolyPower >= 3 || MeHasAura(90174)) &&
                //MyAuraTimeLeft("Eternal Flame", UnitHeal) < 1500 && //Enable recast
                (HealWeightUnitHeal <= THSettings.Instance.WordofGloryHolyHP ||
                 MeHasAura(90174) &&
                 MyAuraTimeLeft(90174, Me) < 3000) &&
                Healable(UnitHeal) &&
                CanCastCheck("Eternal Flame"),
                new Action(delegate { CastSpell("Eternal Flame", UnitHeal); }));
        }

        #endregion

        #region EternalFlameBlanket

        private static WoWUnit UnitEternalFlameBlanket;

        private static bool GetUnitEternalFlameBlanket()
        {
            UnitEternalFlameBlanket = null;

            UnitEternalFlameBlanket = NearbyFriendlyPlayers.OrderBy(HealWeight).FirstOrDefault(
                unit =>
                BasicCheck(unit) &&
                !MyAura("Eternal Flame", unit) &&
                Healable(unit));

            return BasicCheck(UnitEternalFlameBlanket);
        }

        private static Composite EternalFlameBlanket()
        {
            return new Decorator(
                ret =>
                THSettings.Instance.EternalFlameBlanket &&
                //SSpellManager.HasSpell("Eternal Flame") &&
                !HasAuraPreparation &&
                !HasAuraArenaPreparation &&
                //!Me.Mounted &&
                (PlayerHolyPower >= THSettings.Instance.EternalFlameBlanketHolyPower ||
                 MeHasAura(90174)) &&
                GetUnitEternalFlameBlanket() &&
                CanCastCheck("Eternal Flame"),
                new Action(delegate { CastSpell("Eternal Flame", UnitEternalFlameBlanket); })
                );
        }

        #endregion

        #region EternalFlameTank

        private static WoWUnit UnitTankEternalFlame;

        private static bool GetUnitTankEternalFlame()
        {
            UnitTankEternalFlame = null;
            UnitTankEternalFlame = NearbyFriendlyUnits.OrderBy(HealWeight).FirstOrDefault(
                unit =>
                BasicCheck(unit) &&
                unit.Combat &
                unit.HasAura("Vengeance") &&
                IsEnemy(unit.CurrentTarget) &&
                unit.CurrentTarget.CurrentTarget == unit &&
                MyAuraTimeLeft("Eternal Flame", unit) <= 1500 &&
                Healable(unit));

            return BasicCheck(UnitTankEternalFlame);
        }

        private static Composite EternalFlameTank()
        {
            return new Decorator(
                ret =>
                THSettings.Instance.WordofGloryHoly &&
                //SSpellManager.HasSpell("Eternal Flame") &&
                GetUnitTankEternalFlame() &&
                (PlayerHolyPower >= 3 || MeHasAura(90174)) &&
                CanCastCheck("Eternal Flame"),
                new Action(delegate { CastSpell("Eternal Flame", UnitTankEternalFlame); }));
        }

        #endregion

        #region ExecutionSentence

        private static WoWUnit UnitExecutionSentenceHoly;

        private static bool GetUnitExecutionSentenceHoly()
        {
            UnitExecutionSentenceHoly = null;

            if (InArena || InBattleground)
            {
                UnitExecutionSentenceHoly =
                    NearbyUnFriendlyPlayers.OrderBy(unit => unit.HealthPercent).FirstOrDefault(
                        unit =>
                        BasicCheck(unit) &&
                        unit.HealthPercent <= THSettings.Instance.ExecutionSentenceEnemyHP &&
                        FacingOverride(unit) &&
                        !InvulnerableSpell(unit) &&
                        Attackable(unit, 40));
            }
            else
            {
                UnitExecutionSentenceHoly =
                    NearbyUnFriendlyUnits.OrderByDescending(unit => unit.HealthPercent).FirstOrDefault(
                        unit =>
                        BasicCheck(unit) &&
                        unit.HealthPercent <= THSettings.Instance.ExecutionSentenceEnemyHP &&
                        FacingOverride(unit) &&
                        !InvulnerableSpell(unit) &&
                        Attackable(unit, 40));
            }

            return BasicCheck(UnitExecutionSentenceHoly);
        }

        private static Composite ExecutionSentence()
        {
            return new PrioritySelector(
                new Decorator(
                    ret =>
                    THSettings.Instance.ExecutionSentenceFriend &&
                    //SSpellManager.HasSpell("Execution Sentence") &&
                    //!Me.Mounted &&
                    HealWeightUnitHeal <= THSettings.Instance.ExecutionSentenceFriendHP &&
                    UnitHeal.Combat &&
                    //((InDungeon || InRaid) && UnitHeal.HasAura("Vengeance") ||
                    // UnitHeal == Me ||
                    // HasOneAura(UnitHeal,
                    //            new HashSet<string>
                    //                {
                    //                    "Alliance Flag",
                    //                    "Horde Flag",
                    //                    "Netherstorm Flag",
                    //                    "Orb of Power",
                    //                })) &&
                    CanCastCheck("Execution Sentence"),
                    new Action(delegate { CastSpell("Execution Sentence", UnitHeal, "ExecutionSentenceFriend"); })),
                new Decorator(
                    ret =>
                    THSettings.Instance.ExecutionSentenceEnemy &&
                    //SSpellManager.HasSpell("Execution Sentence") &&
                    Me.Specialization != WoWSpec.PaladinHoly &&
                    //!Me.Mounted &&
                    CurrentTargetAttackable(40) &&
                    !Me.CurrentTarget.IsPet &&
                    FacingOverride(Me.CurrentTarget) &&
                    !InvulnerableSpell(Me.CurrentTarget) &&
                    Me.CurrentTarget.HealthPercent <= THSettings.Instance.ExecutionSentenceEnemyHP &&
                    CanCastCheck("Execution Sentence"),
                    new Action(delegate
                        {
                            SafelyFacingTarget(Me.CurrentTarget);
                            CastSpell("Execution Sentence", Me.CurrentTarget, "ExecutionSentenceEnemy");
                        })),
                new Decorator(
                    ret =>
                    THSettings.Instance.ExecutionSentenceEnemy &&
                    //SSpellManager.HasSpell("Execution Sentence") &&
                    Me.Specialization == WoWSpec.PaladinHoly &&
                    //!Me.Mounted &&
                    GetUnitExecutionSentenceHoly() &&
                    CanCastCheck("Execution Sentence"),
                    new Action(delegate
                        {
                            SafelyFacingTarget(UnitExecutionSentenceHoly);
                            CastSpell("Execution Sentence", UnitExecutionSentenceHoly, "UnitExecutionSentenceHoly");
                        }))
                );
        }

        #endregion

        #region Exorcism

        private static Composite Exorcism()
        {
            return new Decorator(
                ret =>
                //_lastCastSpell != "Exorcism" &&
                THSettings.Instance.Exorcism &&
                //SSpellManager.HasSpell("Exorcism") &&
                //!Me.Mounted &&
                (CurrentTargetAttackable(5) ||
                 !HasGlyph.Contains("122028") &&
                 CurrentTargetAttackable(30)) &&
                FacingOverride(Me.CurrentTarget) &&
                !InvulnerableSpell(Me.CurrentTarget) &&
                (PlayerHolyPower < Me.MaxHolyPower || GetDistance(Me.CurrentTarget) > 5) &&
                CanCastCheck("Exorcism"),
                new Action(delegate
                    {
                        //
                        SafelyFacingTarget(Me.CurrentTarget);
                        CastSpell("Exorcism", Me.CurrentTarget);
                    })
                );
        }

        #endregion

        #region FlashofLight

        private static Composite FlashofLight()
        {
            return new Decorator(
                ret =>
                THSettings.Instance.FlashofLightHoly &&
                //SSpellManager.HasSpell("Flash of Light") &&
                HealWeightUnitHeal <= THSettings.Instance.FlashofLightHolyHP &&
                (Me.Combat || UnitHeal.Combat) &&
                //!Blacklist.Contains(UnitHeal.Guid, BlacklistFlags.All) &&
                !IsMoving(Me) &&
                !HoldonDivinePleaHP() &&
                Healable(UnitHeal) &&
                CanCastCheck("Flash of Light"),
                new Action(delegate
                    {
                        //Logging.Write(LogLevel.Diagnostic, "FlashofLight HealRotationCastComp");
                        CastSpell("Flash of Light", UnitHeal);
                    }));
        }

        #endregion

        #region FlashofLightBubble

        private static Composite FlashofLightBubble()
        {
            return new Decorator(
                ret =>
                //SSpellManager.HasSpell("Flash of Light") &&
                (InBattleground ||
                 InArena) &&
                HasOneAura(Me,
                           new HashSet<string>
                               {
                                   "Divine Shield",
                                   "Devotion Aura",
                                   "Hand of Protection",
                               }) &&
                //(MeHasAura("Divine Shield") ||
                // MeHasAura("Devotion Aura") ||
                // MeHasAura("Hand of Protection")) &&
                !IsMoving(Me) &&
                //(Me.Combat || UnitHeal.Combat) &&
                //!Blacklist.Contains(UnitHeal.Guid, BlacklistFlags.All) &&
                //!HoldonDivinePleaHP() &&
                HealWeightUnitHeal <= THSettings.Instance.DoNotHealAbove &&
                Healable(UnitHeal) &&
                CanCastCheck("Flash of Light"),
                new Action(delegate
                    {
                        //Logging.Write(LogLevel.Diagnostic, "FlashofLight Bubble");
                        //Logging.Write("Bubble Heal - Flash of Light");
                        CastSpell("Flash of Light", UnitHeal, "FlashofLightBubble");
                    }));
        }

        #endregion

        #region FlashofLightFriendRet

        private static DateTime FlashofLightDPSSpec;

        private static Composite FlashofLightFriendRet()
        {
            return new Decorator(
                ret =>
                THSettings.Instance.FlashofLightFriendRet &&
                //SSpellManager.HasSpell("Flash of Light") &&
                FlashofLightDPSSpec < DateTime.Now &&
                //!Me.Mounted &&
                !InDungeon &&
                !InRaid &&
                !IsMoving(Me) &&
                //Me.CurrentMana > Me.MaxMana*0.378 &&
                CountDPSTarget(Me) == 0 &&
                BasicCheck(UnitHeal) &&
                HealWeightUnitHeal <= THSettings.Instance.FlashofLightFriendRetHP &&
                CanCastCheck("Flash of Light"),
                new Action(delegate
                    {
                        if (IsMoving(Me) && IsMoving(Me))
                        {
                            Navigator.PlayerMover.MoveStop();
                            WoWMovement.MoveStop();
                        }
                        //Logging.Write(LogLevel.Diagnostic, "FlashofLightFriendRet");
                        DoNotMove = DateTime.Now + TimeSpan.FromSeconds(1);
                        FlashofLightDPSSpec = DateTime.Now + TimeSpan.FromMilliseconds(2000);
                        CastSpell("Flash of Light", UnitHeal, "FlashofLightFriendRet");
                        if (DoNotMove < DateTime.Now)
                        {
                            return RunStatus.Running;
                        }
                        return RunStatus.Success;
                    })
                );
        }

        #endregion

        #region FlashofLightMeRet

        private static Composite FlashofLightMeRet()
        {
            return new Decorator(
                ret =>
                THSettings.Instance.FlashofLightMeRet &&
                //SSpellManager.HasSpell("Flash of Light") &&
                FlashofLightDPSSpec < DateTime.Now &&
                //!Me.Mounted &&
                !InDungeon &&
                !InRaid &&
                !IsMoving(Me) &&
                CountDPSTarget(Me) == 0 &&
                HealWeightMe <= THSettings.Instance.FlashofLightMeRetHP &&
                CanCastCheck("Flash of Light"),
                new Action(delegate
                    {
                        DoNotMove = DateTime.Now + TimeSpan.FromSeconds(1);
                        FlashofLightDPSSpec = DateTime.Now + TimeSpan.FromMilliseconds(2000);
                        CastSpell("Flash of Light", Me, "FlashofLightMeRet");
                        if (DoNotMove < DateTime.Now)
                        {
                            return RunStatus.Running;
                        }
                        return RunStatus.Success;
                    })
                );
        }

        #endregion

        #region FlashofLightMeTopUpRet

        private static Composite FlashofLightMeTopUpRet()
        {
            return new Decorator(
                ret =>
                //SSpellManager.HasSpell("Flash of Light") &&
                FlashofLightDPSSpec < DateTime.Now &&
                //!Me.Mounted &&
                //!Me.Combat &&
                !IsMoving(Me) &&
                CountDPSTarget(Me) == 0 &&
                BasicCheck(UnitHeal) &&
                !UnitHeal.Combat &&
                (HealWeightUnitHeal < THSettings.Instance.DoNotHealAbove &&
                 (InBattleground || InArena)) &&
                CanCastCheck("Flash of Light"),
                new Action(delegate
                    {
                        if (!IsOverrideModeOn && IsMoving(Me))
                        {
                            Navigator.PlayerMover.MoveStop();
                            WoWMovement.MoveStop();
                        }

                        DoNotMove = DateTime.Now + TimeSpan.FromSeconds(1);
                        FlashofLightDPSSpec = DateTime.Now + TimeSpan.FromMilliseconds(2000);
                        CastSpell("Flash of Light", UnitHeal, "FlashofLightMeTopUpRet");
                        if (DoNotMove < DateTime.Now)
                        {
                            return RunStatus.Running;
                        }
                        return RunStatus.Success;
                    })
                );
        }

        #endregion

        #region FlashofLightSelflessHealer

        private static Composite FlashofLightSelflessHealer()
        {
            return new Decorator(
                ret =>
                THSettings.Instance.SelflessHealer &&
                FlashofLightDPSSpec < DateTime.Now &&
                //!Me.Mounted &&
                MyAuraStackCount(114250, Me) > 2 &&
                HealWeightUnitHeal <= THSettings.Instance.SelflessHealerHP &&
                CanCastCheck("Seal of Insight"),
                new Action(delegate
                    {
                        FlashofLightDPSSpec = DateTime.Now + TimeSpan.FromMilliseconds(2000);
                        CastSpell("Flash of Light", UnitHeal, "FlashofLightSelflessHealer");
                    })
                );
        }

        private static Composite FlashofLightSelflessHealerExpiring()
        {
            return new Decorator(
                ret =>
                THSettings.Instance.SelflessHealer &&
                FlashofLightDPSSpec < DateTime.Now &&
                //!Me.Mounted &&
                MyAuraStackCount(114250, Me) > 2 &&
                MyAuraTimeLeft(114250, Me) < 3000 &&
                HealWeightUnitHeal <= THSettings.Instance.DoNotHealAbove &&
                CanCastCheck("Seal of Insight"),
                new Action(delegate
                    {
                        FlashofLightDPSSpec = DateTime.Now + TimeSpan.FromMilliseconds(2000);
                        CastSpell("Flash of Light", UnitHeal, "FlashofLightSelflessHealerExpiring");
                    })
                );
        }

        #endregion

        #region GuardianofAncientKingsHoly

        private static Composite GuardianofAncientKingsHoly()
        {
            return new Decorator(
                ret =>
                THSettings.Instance.GuardianofAncientKingsHoly &&
                //SSpellManager.HasSpell("Guardian of Ancient Kings") &&
                LastBurstCalled < DateTime.Now &&
                HealWeightUnitHeal <= THSettings.Instance.GuardianofAncientKingsHolyHP &&
                UnitHeal.Combat &&
                !UnitHeal.IsPet &&
                (THSettings.Instance.GuardianofAncientKingsHolyNumber <= 1 ||
                 CountUnitHealthBelow(THSettings.Instance.GuardianofAncientKingsHolyHP) >=
                 THSettings.Instance.GuardianofAncientKingsHolyNumber) &&
                !MeHasAura("Divine Shield") &&
                Healable(UnitHeal) &&
                CanCastCheck("Guardian of Ancient Kings", true),
                new Action(delegate
                    {
                        if (Me.IsCasting && !IsHealing())
                        {
                            SpellManager.StopCasting();
                        }
                        LastBurstCalled = DateTime.Now +
                                          TimeSpan.FromSeconds(THSettings.Instance.BurstDelay);
                        CastSpell("Guardian of Ancient Kings", Me, "GuardianofAncientKingsHoly");
                        return RunStatus.Failure;
                    }));
        }

        #endregion

        #region GuardianofAncientKingsAttack

        private static Composite GuardianofAncientKingsRet()
        {
            return new Decorator(
                ret =>
                THSettings.Instance.GuardianofAncientKings &&
                THSettings.Instance.Burst &&
                //SSpellManager.HasSpell("Guardian of Ancient Kings") &&
                //!Me.Mounted &&
                CurrentTargetAttackable(15) &&
                !Me.CurrentTarget.IsFlying &&
                CanCastCheck("Guardian of Ancient Kings"),
                new Action(delegate { CastSpell("Guardian of Ancient Kings", Me, "GuardianofAncientKingsRet"); })
                );
        }

        #endregion

        #region GuardianofAncientKingsProt

        private static Composite GuardianofAncientKingsProt()
        {
            return new Decorator(
                ret =>
                THSettings.Instance.GuardianofAncientKingsProt &&
                //SSpellManager.HasSpell("Guardian of Ancient Kings") &&
                //!Me.Mounted &&
                CurrentTargetAttackable(15) &&
                !Me.CurrentTarget.IsFlying &&
                HealWeightMe < THSettings.Instance.GuardianofAncientKingsProtHP &&
                CanCastCheck("Guardian of Ancient Kings"),
                new Action(delegate { CastSpell("Guardian of Ancient Kings", Me, "GuardianofAncientKingsProt"); })
                );
        }

        #endregion

        #region GetUnitAttackASAP

        private static WoWUnit UnitAttackASAP;

        private static bool GetUnitAttackASAP()
        {
            //using (StyxWoW.Memory.AcquireFrame())
            {
                if (!InArena && !InBattleground)
                {
                    return false;
                }

                UnitAttackASAP = null;

                if (UnitAttackASAP == null)
                {
                    //using (StyxWoW.Memory.AcquireFrame())
                    {
                        UnitAttackASAP = NearbyUnFriendlyPlayers.FirstOrDefault(
                            unit => BasicCheck(unit) &&
                                    unit.IsValid &&
                                    (unit.Class == WoWClass.Rogue ||
                                     unit.Class == WoWClass.Druid) &&
                                    !DebuffDot(unit) &&
                                    Attackable(unit, 40));
                    }
                }


                if (UnitAttackASAP == null)
                {
                    //using (StyxWoW.Memory.AcquireFrame())
                    {
                        UnitAttackASAP = NearbyUnFriendlyUnits.FirstOrDefault(
                            unit => BasicCheck(unit) &&
                                    unit.IsValid &&
                                    (unit.IsTotem &&
                                     (unit.Entry == 53006 ||
                                      unit.Entry == 60561 ||
                                      unit.Entry == 2630 ||
                                      unit.Entry == 59717 ||
                                      unit.Entry == 10467 ||
                                      unit.Entry == 59764 ||
                                      unit.Entry == 61245)) &&
                                    Attackable(unit, 40));
                    }
                }

                return BasicCheck(UnitAttackASAP);
            }
        }

        #endregion

        #region HammerofJustice

        private static WoWUnit UnitHammerofJusticeInterrupt;

        private static bool GetUnitHammerofJusticeInterrupt()
        {
            UnitHammerofJusticeInterrupt = null;

            if (InBattleground || InArena)
            {
                UnitHammerofJusticeInterrupt = NearbyUnFriendlyPlayers.FirstOrDefault(
                    unit => BasicCheck(unit) &&
                            (THSettings.Instance.InterruptAll ||
                             THSettings.Instance.InterruptTarget &&
                             Me.CurrentTarget != null &&
                             unit == Me.CurrentTarget ||
                             THSettings.Instance.InterruptFocus &&
                             Me.FocusedUnit != null &&
                             unit == Me.FocusedUnit) &&
                            !InvulnerableSpell(unit) &&
                            !InvulnerableStun(unit) &&
                            InterruptCheck(unit, THSettings.Instance.HammerofJusticeInterruptMs + MyLatency) &&
                            (//SSpellManager.HasSpell("Fist of Justice") &&
                             Attackable(unit, 20) ||
                             Attackable(unit, 10)));
            }
                //PvE Search
            else
            {
                UnitHammerofJusticeInterrupt = NearbyUnFriendlyUnits.FirstOrDefault(
                    unit => BasicCheck(unit) &&
                            (THSettings.Instance.InterruptAll ||
                             THSettings.Instance.InterruptTarget &&
                             Me.CurrentTarget != null &&
                             unit == Me.CurrentTarget ||
                             THSettings.Instance.InterruptFocus &&
                             Me.FocusedUnit != null &&
                             unit == Me.FocusedUnit) &&
                            FarFriendlyUnits.Contains(unit.CurrentTarget) &&
                            InterruptCheck(unit, THSettings.Instance.HammerofJusticeInterruptMs + MyLatency) &&
                            (//SSpellManager.HasSpell("Fist of Justice") &&
                             Attackable(unit, 20) ||
                             Attackable(unit, 10)));
            }

            return BasicCheck(UnitHammerofJusticeInterrupt);
        }

        private void HammerofJusticeVoid()
        {
            if (THSettings.Instance.HammerofJusticeInterrupt &&
                //SSpellManager.HasSpell("Hammer of Justice") &&
                LastInterrupt < DateTime.Now &&
                GetUnitHammerofJusticeInterrupt() &&
                CanCastCheck("Hammer of Justice"))
            {
                if (Me.IsCasting || Me.IsChanneling)
                {
                    SpellManager.StopCasting();
                }

                while (UnitHammerofJusticeInterrupt.CurrentCastTimeLeft.TotalMilliseconds >
                       THSettings.Instance.HammerofJusticeInterruptMs + MyLatency)
                {
                    Logging.Write("Waiting for Hammer of Justice");
                }

                if (UnitHammerofJusticeInterrupt.IsCasting || UnitHammerofJusticeInterrupt.IsChanneling)
                {
                    CastSpell("Hammer of Justice", UnitHammerofJusticeInterrupt, "HammerofJusticeInterrupt");
                    LastInterrupt = DateTime.Now + TimeSpan.FromMilliseconds(1500);
                }
            }


            //if (THSettings.Instance.HammerofJusticeInterrupt &&
            //    //SSpellManager.HasSpell("Hammer of Justice") &&
            //    (InArena ||
            //     InBattleground) &&
            //    //!Me.Mounted &&
            //    !MeHasAura("Hand of Protection") &&
            //    Me.CurrentTarget.HasAura("Evasion") &&
            //    !InvulnerableSpell(Me.CurrentTarget) &&
            //    !InvulnerableStun(Me.CurrentTarget) &&
            //    (//SSpellManager.HasSpell("Fist of Justice") &&
            //     Attackable(Me.CurrentTarget, 20) ||
            //     Attackable(Me.CurrentTarget, 10)) &&
            //    CanCastCheck("Hammer of Justice"))
            //{
            //    CastSpell("Hammer of Justice", Me.CurrentTarget, "HammerofJustice Evasion");
            //}
        }

        #endregion

        #region HammerofJusticeBurstRet

        private static Composite HammerofJusticeBurstRet()
        {
            return new Decorator(
                ret =>
                THSettings.Instance.Burst &&
                //SSpellManager.HasSpell("Hammer of Justice") &&
                //SSpellManager.HasSpell("Guardian of Ancient Kings") &&
                //!Me.Mounted &&
                CurrentTargetAttackable(10) &&
                Me.CurrentTarget.IsPlayer &&
                !InvulnerableSpell(Me.CurrentTarget) &&
                !InvulnerableStun(Me.CurrentTarget) &&
                SpellManager.Spells["Guardian of Ancient Kings"].CooldownTimeLeft.TotalSeconds < 294 &&
                SpellManager.Spells["Guardian of Ancient Kings"].CooldownTimeLeft.TotalSeconds > 0 &&
                CanCastCheck("Hammer of Justice"),
                new Action(delegate { CastSpell("Hammer of Justice", Me.CurrentTarget, "HammerofJusticeBurstRet"); })
                );
        }

        #endregion

        #region HammerofJusticeEnemyLow

        private static WoWUnit UnitHammerofJusticeEnemyLow;

        private static bool GetUnitHammerofJusticeEnemyLow()
        {
            UnitHammerofJusticeEnemyLow = null;

            UnitHammerofJusticeEnemyLow = NearbyUnFriendlyPlayers.OrderBy(unit => unit.HealthPercent).FirstOrDefault(
                unit => BasicCheck(unit) &&
                        (Me.Specialization == WoWSpec.PaladinHoly ||
                         Me.CurrentTarget != null &&
                         unit == Me.CurrentTarget) &&
                        unit.HealthPercent <= THSettings.Instance.HammerofJusticeEnemyLowHP &&
                        unit.Class != WoWClass.DeathKnight &&
                        TalentSort(unit) != 4 &&
                        !InvulnerableStun(unit) &&
                        !InvulnerableSpell(unit) &&
                        (Attackable(unit, 10) ||
                         SpellManager.HasSpell("Fist of Justice") &&
                         Attackable(unit, 20)));

            return BasicCheck(UnitHammerofJusticeEnemyLow);
        }

        private static Composite HammerofJusticeEnemyLow()
        {
            return new Decorator(
                ret =>
                THSettings.Instance.HammerofJusticeEnemyLow &&
                //SSpellManager.HasSpell("Hammer of Justice") &&
                //!Me.Mounted &&
                GetUnitHammerofJusticeEnemyLow() &&
                CanCastCheck("Hammer of Justice"),
                new Action(
                    delegate { CastSpell("Hammer of Justice", UnitHammerofJusticeEnemyLow, "HammerofJusticeEnemyLow"); }));
        }

        #endregion

        #region HammerofJusticeEnemyUsingCD

        private static WoWUnit UnitHammerofJusticeEnemyUsingCD;

        private static bool GetUnitHammerofJusticeEnemyUsingCD()
        {
            UnitHammerofJusticeEnemyUsingCD = null;

            UnitHammerofJusticeEnemyUsingCD = NearbyUnFriendlyPlayers.OrderByDescending(unit => unit.HealthPercent)
                                                                     .FirstOrDefault(
                                                                         unit => BasicCheck(unit) &&
                                                                                 !InvulnerableStun(unit) &&
                                                                                 !InvulnerableSpell(unit) &&
                                                                                 BuffBurst(unit) &&
                                                                                 (Attackable(unit, 10) ||
                                                                                  //SSpellManager.HasSpell(
                                                                                      "Fist of Justice") &&
                                                                                  Attackable(unit, 20)));

            return BasicCheck(UnitHammerofJusticeEnemyUsingCD);
        }

        private static Composite HammerofJusticeEnemyUsingCD()
        {
            return new Decorator(
                ret =>
                THSettings.Instance.HammerofJusticeEnemyUsingCD &&
                //SSpellManager.HasSpell("Hammer of Justice") &&
                ////!Me.Mounted &&
                GetUnitHammerofJusticeEnemyUsingCD() &&
                CanCastCheck("Hammer of Justice"),
                new Action(
                    delegate
                        {
                            CastSpell("Hammer of Justice", UnitHammerofJusticeEnemyUsingCD,
                                      "HammerofJusticeEnemyUsingCD");
                        }));
        }

        #endregion

        #region HammeroftheRighteousRet

        private static Composite HammeroftheRighteousRet()
        {
            return new Decorator(
                ret =>
                THSettings.Instance.HammeroftheRighteousRet &&
                //SSpellManager.HasSpell("Hammer of the Righteous") &&
                ////!Me.Mounted &&
                !MeHasAura("Hand of Protection") &&
                !InArena &&
                !InBattleground &&
                PlayerHolyPower < Me.MaxHolyPower &&
                CurrentTargetAttackable(5) &&
                FacingOverride(Me.CurrentTarget) &&
                CountEnemyNeary(Me, 8) >= THSettings.Instance.HammeroftheRighteousRetNumber &&
                CanCastCheck("Hammer of the Righteous"),
                new Action(delegate
                    {
                        SafelyFacingTarget(Me.CurrentTarget);
                        CastSpell("Hammer of the Righteous", Me.CurrentTarget, "HammeroftheRighteousRet");
                    })
                );
        }

        #endregion

        #region HammeroftheRighteousRetPvE4PlusUnit

        //private static Composite HammeroftheRighteousRetPvE4PlusUnit()
        //{
        //    return new Decorator(
        //        ret =>
        //        THSettings.Instance.HammeroftheRighteous &&
        //        THSettings.Instance.HammeroftheRighteousRetNumber >= 4 &&
        //        //SSpellManager.HasSpell("Hammer of the Righteous") &&
        //        ////!Me.Mounted &&
        //        !MeHasAura("Hand of Protection") &&
        //        !InArena &&
        //        !InBattleground &&
        //        PlayerHolyPower < Me.MaxHolyPower &&
        //        CurrentTargetAttackable(5) &&
        //        FacingOverride(Me.CurrentTarget) &&
        //        CountEnemyNeary(Me, 10) >= THSettings.Instance.HammeroftheRighteousRetNumber &&
        //        CanCastCheck("Hammer of the Righteous"),
        //        new Action(delegate
        //            {
        //                SafelyFacingTarget(Me.CurrentTarget);
        //                CastSpell("Hammer of the Righteous", Me.CurrentTarget);
        //            })
        //        );
        //}

        #endregion

        #region HammeroftheRighteousProtection

        private static Composite HammeroftheRighteousProt()
        {
            return new Decorator(
                ret =>
                THSettings.Instance.HammeroftheRighteousProt &&
                //SSpellManager.HasSpell("Hammer of the Righteous") &&
                ////!Me.Mounted &&
                !MeHasAura("Hand of Protection") &&
                (!THSettings.Instance.ShieldofRighterous ||
                 PlayerHolyPower < Me.MaxHolyPower) &&
                CurrentTargetAttackable(5) &&
                FacingOverride(Me.CurrentTarget) &&
                (!Me.CurrentTarget.HasAura("Weakened Blows") ||
                 CountEnemyNeary(Me, 10) >= THSettings.Instance.HammeroftheRighteousProtUnit) &&
                CanCastCheck("Hammer of the Righteous"),
                new Action(delegate
                    {
                        SafelyFacingTarget(Me.CurrentTarget);
                        CastSpell("Hammer of the Righteous", Me.CurrentTarget, "HammeroftheRighteousProt");
                    })
                );
        }

        #endregion

        #region HammeroftheRighteousRetWeakenedBlows

        private static Composite HammeroftheRighteousRetWeakenedBlows()
        {
            return new Decorator(
                ret =>
                THSettings.Instance.HammeroftheRighteousRetWeakenedBlows &&
                //SSpellManager.HasSpell("Hammer of the Righteous") &&
                ////!Me.Mounted &&
                !MeHasAura("Hand of Protection") &&
                CurrentTargetAttackable(5) &&
                TalentSort(Me.CurrentTarget) == 1 &&
                FacingOverride(Me.CurrentTarget) &&
                !Me.CurrentTarget.HasAura("Weakened Blows") &&
                CanCastCheck("Hammer of the Righteous"),
                new Action(delegate
                    {
                        SafelyFacingTarget(Me.CurrentTarget);
                        CastSpell("Hammer of the Righteous", Me.CurrentTarget, "HammeroftheRighteousRetWeakenedBlows");
                    })
                );
        }

        #endregion

        #region HammerofWrathCurrentTarget

        private static Composite HammerofWrathCurrentTarget()
        {
            return new Decorator(
                ret =>
                //SSpellManager.HasSpell("Hammer of Wrath") &&
                LastCastSpell != "Hammer of Wrath" &&
                (THSettings.Instance.HammerofWrathHoly ||
                 Me.Specialization != WoWSpec.PaladinHoly) &&
                ////!Me.Mounted &&
                !MeHasAura("Hand of Protection") &&
                CurrentTargetAttackable(30) &&
                FacingOverride(Me.CurrentTarget) &&
                (Me.CurrentTarget.HealthPercent < 20 ||
                 MeHasAura("Avenging Wrath") &&
                 Me.Specialization != WoWSpec.PaladinHoly) &&
                !InvulnerableSpell(Me.CurrentTarget) &&
                CanCastCheck("Hammer of Wrath"),
                new Action(delegate
                    {
                        SafelyFacingTarget(Me.CurrentTarget);
                        CastSpell("Hammer of Wrath", Me.CurrentTarget);
                    })
                );
        }

        #endregion

        #region HammerofWrathUnitHammerofWrath

        private static WoWUnit UnitHammerofWrath;

        private static bool GetUnitHammerofWrath()
        {
            //using (StyxWoW.Memory.AcquireFrame())
            {
                UnitHammerofWrath = null;

                UnitHammerofWrath = NearbyUnFriendlyPlayers.FirstOrDefault(
                    unit =>
                    GetDistance(unit) < 30 &&
                    unit.HealthPercent <= 20 &&
                    !Invulnerable(unit) &&
                    FacingOverride(unit) &&
                    InLineOfSpellSightCheck(unit));

                return BasicCheck(UnitHammerofWrath);
            }
        }

        private static Composite HammerofWrathUnitHammerofWrath()
        {
            return new Decorator(
                ret =>
                //SSpellManager.HasSpell("Hammer of Wrath") &&
                LastCastSpell != "Hammer of Wrath" &&
                (THSettings.Instance.HammerofWrathHoly ||
                 Me.Specialization != WoWSpec.PaladinHoly) &&
                ////!Me.Mounted &&
                !MeHasAura("Hand of Protection") &&
                GetUnitHammerofWrath() &&
                FacingOverride(UnitHammerofWrath) &&
                GetSpellCooldown("Hammer of Wrath").TotalMilliseconds <= MyLatency,
                new Action(delegate
                    {
                        SafelyFacingTarget(UnitHammerofWrath);
                        CastSpell("Hammer of Wrath", UnitHammerofWrath);
                    })
                );
        }

        #endregion

        #region HandofFreedomMyself

        private static DateTime LastHand;

        private static Composite HandofFreedomMyself()
        {
            return new Decorator(
                ret =>
                THSettings.Instance.HandofFreedomMyself &&
                LastHand < DateTime.Now &&
                //SSpellManager.HasSpell("Hand of Freedom") &&
                ////!Me.Mounted &&
                CurrentTargetAttackable(60) &&
                GetDistance(Me.CurrentTarget) > 5 &&
                DebuffRootorSnare(Me) &&
                !GetMyHandonUnit(Me) &&
                CanCastCheck("Hand of Freedom"),
                new Action(delegate
                    {
                        LastHand = DateTime.Now + TimeSpan.FromMilliseconds(1500);
                        CastSpell("Hand of Freedom", Me, "HandofFreedomMyself");
                    })
                );
        }

        #endregion

        #region HandofFreedomMyselfHoly

        private static Composite HandofFreedomMyselfHoly()
        {
            return new Decorator(
                ret =>
                THSettings.Instance.HandofFreedomMyself &&
                LastHand < DateTime.Now &&
                //SSpellManager.HasSpell("Hand of Freedom") &&
                ////!Me.Mounted &&
                (IsMoving(Me) || IsOverrideModeOn) &&
                DebuffRootorSnare(Me) &&
                !GetMyHandonUnit(Me) &&
                CanCastCheck("Hand of Freedom"),
                new Action(delegate
                    {
                        LastHand = DateTime.Now + TimeSpan.FromMilliseconds(1500);
                        CastSpell("Hand of Freedom", Me);
                    })
                );
        }

        #endregion

        #region HandofFreedomFriend

        private static WoWUnit UnitHandofFreedom;

        private static bool GetUnitHandofFreedom()
        {
            UnitHandofFreedom = null;

            if (THSettings.Instance.HandofFreedomMelee)
            {
                UnitHandofFreedom = NearbyFriendlyPlayers.FirstOrDefault(
                    unit => BasicCheck(unit) &&
                            GetDistance(unit) < 30 &&
                            unit.Class != WoWClass.Paladin &&
                            unit.Class != WoWClass.Druid &&
                            unit.Class != WoWClass.Shaman &&
                            TalentSort(unit) == 1 &&
                            HealWeight(unit) > 30 &&
                            !GetMyHandonUnit(unit) &&
                            !DebuffCC(unit) &&
                            DebuffRootorSnare(unit) &&
                            IsEnemy(unit.CurrentTarget) &&
                            unit.Location.Distance(unit.CurrentTarget.Location) > 6 &&
                            Healable(unit));
            }

            if (UnitHandofFreedom == null && THSettings.Instance.HandofFreedomHealer)
            {
                UnitHandofFreedom = NearbyFriendlyPlayers.FirstOrDefault(
                    unit => BasicCheck(unit) &&
                            GetDistance(unit) < 30 &&
                            unit.Class != WoWClass.Paladin &&
                            unit.Class != WoWClass.Druid &&
                            unit.Class != WoWClass.Shaman &&
                            TalentSort(unit) == 4 &&
                            HealWeight(unit) > 10 &&
                            !GetMyHandonUnit(unit) &&
                            !DebuffCC(unit) &&
                            DebuffRootorSnare(unit) &&
                            CountMeleeDPSTarget(unit) > 0 &&
                            unit.Location.Distance(unit.CurrentTarget.Location) > 6 &&
                            Healable(unit));
            }

            if (UnitHandofFreedom == null && THSettings.Instance.HandofFreedomCaster)
            {
                UnitHandofFreedom = NearbyFriendlyPlayers.FirstOrDefault(
                    unit => BasicCheck(unit) &&
                            GetDistance(unit) < 30 &&
                            TalentSort(unit) > 1 &&
                            TalentSort(unit) < 4 &&
                            HealWeight(unit) > 30 &&
                            !GetMyHandonUnit(unit) &&
                            !DebuffCC(unit) &&
                            DebuffRootorSnare(unit) &&
                            CountMeleeDPSTarget(unit) > 0 &&
                            unit.Location.Distance(unit.CurrentTarget.Location) > 6 &&
                            Healable(unit));
            }

            return BasicCheck(UnitHandofFreedom);
        }

        private static Composite HandofFreedomFriend()
        {
            return new Decorator(
                ret =>
                (THSettings.Instance.HandofFreedomMelee ||
                 THSettings.Instance.HandofFreedomHealer ||
                 THSettings.Instance.HandofFreedomCaster) &&
                //SSpellManager.HasSpell("Hand of Freedom") &&
                LastHand < DateTime.Now &&
                ////!Me.Mounted &&
                GetUnitHandofFreedom() &&
                CanCastCheck("Hand of Freedom"),
                new Action(delegate
                    {
                        LastHand = DateTime.Now + TimeSpan.FromMilliseconds(1500);
                        CastSpell("Hand of Freedom", UnitHandofFreedom);
                    })
                );
        }

        #endregion

        #region HandofProtectionMe

        private static Composite HandofProtectionMe()
        {
            return new Decorator(
                ret =>
                THSettings.Instance.HandofProtection &&
                //SSpellManager.HasSpell("Hand of Protection") &&
                LastHand < DateTime.Now &&
                ////!Me.Mounted &&
                Me.Combat &&
                !HasOneAura(Me,
                            new HashSet<string>
                                {
                                    "Alliance Flag",
                                    "Horde Flag",
                                    "Netherstorm Flag",
                                    "Orb of Power",
                                }) &&
                HealWeightMe < THSettings.Instance.HandofProtectionHP &&
                CountPhysicDPSTarget(Me) > 0 &&
                SpellManager.Spells["Divine Shield"].CooldownTimeLeft.TotalSeconds > 10 &&
                CanCastCheck("Hand of Protection"),
                new Action(delegate
                    {
                        LastHand = DateTime.Now + TimeSpan.FromMilliseconds(1500);
                        CastSpell("Hand of Protection", Me, "HandofProtectionMe");
                    })
                );
        }

        #endregion

        #region HandofProtectionFriendRemoveCC

        private static WoWPlayer PlayerHandofProtectionFriendRemoveCC;

        private static bool GetPlayerHandofProtectionFriendRemoveCC()
        {
            PlayerHandofProtectionFriendRemoveCC = null;

            PlayerHandofProtectionFriendRemoveCC = NearbyFriendlyPlayers.FirstOrDefault(
                unit => BasicCheck(unit) &&
                        HasOneAura(unit, new HashSet<string> {"Blind", "Intimidation Shout"}) &&
                        !HasOneAura(unit,
                                    new HashSet<string>
                                        {
                                            "Forbearance",
                                            "Alliance Flag",
                                            "Horde Flag",
                                            "Netherstorm Flag"
                                        }) &&
                        //HasOneAura(unit, new HashSet<string>({"Blind", "Intimidation Shout"})) &&
                        //(unit.HasAura("Blind") ||
                        // unit.HasAura("Intimidation Shout")) &&
                        //!unit.HasAura("Forbearance") &&
                        //!unit.HasAura("Alliance Flag") &&
                        //!unit.HasAura("Horde Flag") &&
                        //!unit.HasAura("Netherstorm Flag") &&
                        //!unit.HasAura("Orb of Power") &&
                        (unit != Me ||
                         unit == Me &&
                         SpellManager.Spells["Divine Shield"].CooldownTimeLeft.TotalSeconds > 60));

            return BasicCheck(PlayerHandofProtectionFriendRemoveCC);
        }

        private static Composite HandofProtectionFriendRemoveCC()
        {
            return new Decorator(
                ret =>
                THSettings.Instance.HandofProtectionHPRemoveCC &&
                //SSpellManager.HasSpell("Hand of Protection") &&
                ////!Me.Mounted &&
                LastHand < DateTime.Now &&
                GetPlayerHandofProtectionFriendRemoveCC() &&
                CanCastCheck("Hand of Protection"),
                new Action(delegate
                    {
                        LastHand = DateTime.Now + TimeSpan.FromMilliseconds(1500);
                        CastSpell("Hand of Protection", PlayerHandofProtectionFriendRemoveCC);
                        PlayerHandofProtectionFriendRemoveCC = null;
                    }));
        }

        #endregion

        #region HandofProtectionFriend

        private static Composite HandofProtectionFriend()
        {
            return new Decorator(
                ret =>
                THSettings.Instance.HandofProtection &&
                //SSpellManager.HasSpell("Hand of Protection") &&
                ////!Me.Mounted &&
                LastHand < DateTime.Now &&
                HealWeightUnitHeal < THSettings.Instance.HandofProtectionHP &&
                UnitHeal.Distance < 30 &&
                UnitHeal.Combat &&
                HealWeightUnitHeal > 5 &&
                !UnitHeal.HasAura("Forbearance") &&
                !Invulnerable(UnitHeal) &&
                (UnitHeal != Me ||
                 UnitHeal == Me && SpellManager.Spells["Divine Shield"].CooldownTimeLeft.TotalSeconds > 10) &&
                !HasOneAura(UnitHeal,
                            new HashSet<string>
                                {
                                    "Alliance",
                                    "Alliance Flag",
                                    "Horde Flag",
                                    "Netherstorm Flag",
                                    "Orb of Power",
                                }) &&
                (!UnitHeal.HasAura("Vengeance") ||
                 InBattleground ||
                 InArena) &&
                CountPhysicDPSTarget(UnitHeal) > 0 &&
                CanCastCheck("Hand of Protection"),
                new Action(delegate
                    {
                        LastHand = DateTime.Now + TimeSpan.FromMilliseconds(1500);
                        CastSpell("Hand of Protection", UnitHeal, "HandofProtectionFriend");
                    }));
        }

        #endregion

        #region HandofPurity

        private static WoWPlayer PlayerHandofPurityDebuff;

        private static bool GetPlayerHandofPurityDebuff()
        {
            PlayerHandofPurityDebuff = null;

            PlayerHandofPurityDebuff = NearbyFriendlyPlayers.OrderByDescending(DebuffDotCount).FirstOrDefault(
                unit =>
                BasicCheck(unit) &&
                !GetMyHandonUnit(unit) &&
                !Invulnerable(unit) &&
                DebuffDotCount(unit) >= THSettings.Instance.HandofPurityDebuffNumber &&
                Healable(unit));

            return BasicCheck(PlayerHandofPurityDebuff);
        }

        private static Composite HandofPurity()
        {
            return new PrioritySelector(
                new Decorator(
                    ret =>
                    THSettings.Instance.HandofPurity &&
                    //SSpellManager.HasSpell("Hand of Purity") &&
                    ////!Me.Mounted &&
                    LastHand < DateTime.Now &&
                    HealWeightUnitHeal < THSettings.Instance.HandofPurityHP &&
                    HealWeightUnitHeal > 5 &&
                    UnitHeal.Distance < 40 &&
                    UnitHeal.Combat &&
                    !GetMyHandonUnit(UnitHeal) &&
                    !Invulnerable(UnitHeal) &&
                    (UnitHeal != Me ||
                     UnitHeal == Me &&
                     SpellManager.Spells["Divine Shield"].CooldownTimeLeft.TotalSeconds > 10) &&
                    CanCastCheck("Hand of Purity"),
                    new Action(delegate
                        {
                            LastHand = DateTime.Now + TimeSpan.FromMilliseconds(1500);
                            CastSpell("Hand of Purity", UnitHeal, "HandofPurity");
                        })),
                new Decorator(
                    ret =>
                    THSettings.Instance.HandofPurityDebuff &&
                    //SSpellManager.HasSpell("Hand of Purity") &&
                    ////!Me.Mounted &&
                    LastHand < DateTime.Now &&
                    GetPlayerHandofPurityDebuff() &&
                    CanCastCheck("Hand of Purity"),
                    new Action(delegate
                        {
                            LastHand = DateTime.Now + TimeSpan.FromMilliseconds(1500);
                            CastSpell("Hand of Purity", PlayerHandofPurityDebuff, "HandofPurityDebuff");
                        }))
                );
        }

        #endregion

        #region HandofSacrificeFriend

        private static Composite HandofSacrificeFriend()
        {
            return new Decorator(
                ret =>
                THSettings.Instance.HandofSacrifice &&
                //SSpellManager.HasSpell("Hand of Sacrifice") &&
                ////!Me.Mounted &&
                LastHand < DateTime.Now &&
                HealWeightMe > THSettings.Instance.PriorityHeal &&
                HealWeightUnitHeal <= THSettings.Instance.HandofSacrificeHP &&
                HealWeightUnitHeal > 5 &&
                UnitHeal.Combat &&
                !Invulnerable(UnitHeal) &&
                !GetMyHandonUnit(UnitHeal) &&
                CountDPSTarget(UnitHeal) > 0 &&
                CanCastCheck("Hand of Sacrifice"),
                new Action(delegate
                    {
                        LastHand = DateTime.Now + TimeSpan.FromMilliseconds(1500);
                        CastSpell("Hand of Sacrifice", UnitHeal);
                    }));
        }

        #endregion

        #region HandofSacrificeFriendRetRemoveCC

        private static WoWUnit PlayerFriendlyHandofSacASAP;

        private static bool GetPlayerFriendlyHandofSacASAP()
        {
            PlayerFriendlyHandofSacASAP = null;

            PlayerFriendlyHandofSacASAP = NearbyFriendlyPlayers.FirstOrDefault(
                unit => BasicCheck(unit) &&
                        (THSettings.Instance.HandofSacCCRemoveHealer && TalentSort(unit) == 4 ||
                         THSettings.Instance.HandofSacCCRemoveCaster &&
                         (TalentSort(unit) == 2 ||
                          TalentSort(unit) == 3) ||
                         THSettings.Instance.HandofSacCCRemoveMelee &&
                         TalentSort(unit) == 1) &&
                        DebuffMagicCCDuration(unit, 3000) &&
                        !DebuffDoNotCleanse(unit) &&
                        Healable(unit));

            return BasicCheck(PlayerFriendlyHandofSacASAP);
        }

        private static Composite HandofSacrificeFriendRetRemoveCC()
        {
            return new Decorator(
                ret =>
                (THSettings.Instance.HandofSacCCRemoveMelee ||
                 THSettings.Instance.HandofSacCCRemoveCaster ||
                 THSettings.Instance.HandofSacCCRemoveHealer) &&
                //SSpellManager.HasSpell("Hand of Sacrifice") &&
                ////!Me.Mounted &&
                LastHand < DateTime.Now &&
                GetPlayerFriendlyHandofSacASAP() &&
                CanCastCheck("Hand of Sacrifice"),
                new Action(delegate
                    {
                        LastHand = DateTime.Now + TimeSpan.FromMilliseconds(1500);
                        CastSpell("Hand of Sacrifice", PlayerFriendlyHandofSacASAP);
                    }))
                ;
        }

        #endregion

        #region HandofSalvation

        private static Composite HandofSalvation()
        {
            return new Decorator(
                ret =>
                //THSettings.Instance.HandofSalvation &&
                (InBattleground || InArena) &&
                //SSpellManager.HasSpell("Hand of Salvation") &&
                LastHand < DateTime.Now &&
                ////!Me.Mounted &&
                !GetMyHandonUnit(Me) &&
                GetUnitDispellerAround() &&
                MeHasAura("Divine Plea") &&
                CanCastCheck("Hand of Salvation"),
                new Action(delegate
                    {
                        LastHand = DateTime.Now + TimeSpan.FromMilliseconds(1500);
                        CastSpell("Hand of Salvation", Me);
                    }));
        }

        private static WoWUnit UnitHandofSalvHighThreat;

        private static bool GetUnitHandofSalvHighThreat()
        {
            UnitHandofSalvHighThreat = null;

            UnitHandofSalvHighThreat =
                NearbyFriendlyPlayers.OrderByDescending(unit => Me.CurrentTarget.GetThreatInfoFor(unit).ThreatValue)
                                     .FirstOrDefault(
                                         unit =>
                                         BasicCheck(unit) &&
                                         unit.Combat &&
                                         !unit.HasAura("Vengeance") &&
                                         Me.CurrentTarget.GetThreatInfoFor(unit).RawPercent >=
                                         THSettings.Instance.HandofSalvHighThreatPercent &&
                                         !GetMyHandonUnit(unit) &&
                                         //CountEnemyTargettingUnit(unit, 40) > 0 &&
                                         Healable(unit));

            return BasicCheck(UnitHandofSalvHighThreat);
        }

        private static Composite HandofSalvHighThreat()
        {
            return new Decorator(
                ret =>
                THSettings.Instance.HandofSalvHighThreat &&
                //SSpellManager.HasSpell("Hand of Salvation") &&
                (InRaid || InDungeon) &&
                LastHand < DateTime.Now &&
                ////!Me.Mounted &&
                Me.Combat &&
                CurrentTargetAttackable(30) &&
                GetUnitHandofSalvHighThreat() &&
                CanCastCheck("Hand of Salvation"),
                new Action(delegate
                    {
                        LastHand = DateTime.Now + TimeSpan.FromMilliseconds(1500);
                        CastSpell("Hand of Salvation", UnitHandofSalvHighThreat, "HandofSalvHighThreat");
                    }));
        }

        #endregion

        #region HoldonDivinePleaHP

        private static bool HoldonDivinePleaHP()
        {
            if (!MeHasAura("Divine Plea"))
            {
                return false;
            }

            if (InBattleground || InArena)
            {
                return false;
            }

            if (UnitHeal != null &&
                UnitHeal.IsValid &&
                HealWeightUnitHeal < THSettings.Instance.UrgentHeal)
            {
                return false;
            }

            return true;
        }

        #endregion

        #region HolyAvenger

        private static DateTime LastBurstCalled;

        private static Composite HolyAvenger()
        {
            return new Decorator(
                ret =>
                THSettings.Instance.HolyAvengerHoly &&
                //SSpellManager.HasSpell("Holy Avenger") &&
                LastBurstCalled < DateTime.Now &&
                HealWeightUnitHeal <= THSettings.Instance.HolyAvengerHolyHP &&
                UnitHeal.Combat &&
                !UnitHeal.IsPet &&
                (THSettings.Instance.HolyAvengerHolyNumber <= 1 ||
                 CountUnitHealthBelow(THSettings.Instance.HolyAvengerHolyHP) >=
                 THSettings.Instance.HolyAvengerHolyNumber) &&
                !MeHasAura("Divine Shield") &&
                Healable(UnitHeal) &&
                CanCastCheck("Holy Avenger", true),
                new Action(delegate
                    {
                        if (Me.IsCasting && !IsHealing())
                        {
                            SpellManager.StopCasting();
                        }
                        LastBurstCalled = DateTime.Now +
                                          TimeSpan.FromSeconds(THSettings.Instance.BurstDelay);
                        CastSpell("Holy Avenger", Me);
                        return RunStatus.Failure;
                    }));
        }

        #endregion

        #region HolyAvengerBurstRet

        private static Composite HolyAvengerBurstRet()
        {
            return new Decorator(
                ret =>
                THSettings.Instance.Burst &&
                //SSpellManager.HasSpell("Holy Avenger") &&
                //SSpellManager.HasSpell("Guardian of Ancient Kings") &&
                ////!Me.Mounted &&
                CurrentTargetAttackable(15) &&
                !Me.CurrentTarget.IsFlying &&
                GetSpellCooldown("Guardian of Ancient Kings").TotalSeconds < 294 &&
                GetSpellCooldown("Guardian of Ancient Kings").TotalSeconds > 0 &&
                CanCastCheck("Holy Avenger", true),
                new Action(delegate
                    {
                        CastSpell("Holy Avenger", Me);
                        return RunStatus.Failure;
                    })
                );
        }

        #endregion

        #region HolyLight

        private static Composite HolyLight()
        {
            return new Decorator(
                ret =>
                THSettings.Instance.HolyLight &&
                //SSpellManager.HasSpell("Holy Light") &&
                !IsMoving(Me) &&
                Me.CurrentMana > WoWSpell.FromId(635).PowerCost*2 && //Save Mana for Holy Shock
                HealWeightUnitHeal <= THSettings.Instance.HolyLightHP &&
                (HealWeightUnitHeal > THSettings.Instance.DivineLightHP ||
                 !UnitHeal.Combat &&
                 !Me.Combat) &&
                !HoldonDivinePleaHP() &&
                Healable(UnitHeal) &&
                CanCastCheck("Holy Light"),
                new Action(delegate { CastSpell("Holy Light", UnitHeal); }));
        }

        #endregion

        #region HolyPrism

        private static WoWUnit UnitHolyPrismHoly;

        private static bool GetUnitHolyPrismHoly()
        {
            UnitHolyPrismHoly = null;

            if (InArena || InBattleground)
            {
                UnitHolyPrismHoly =
                    NearbyUnFriendlyPlayers.OrderBy(unit => unit.HealthPercent).FirstOrDefault(
                        unit =>
                        BasicCheck(unit) &&
                        unit.HealthPercent <= THSettings.Instance.HolyPrismEnemyHP &&
                        FacingOverride(unit) &&
                        !InvulnerableSpell(unit) &&
                        Attackable(unit, 40));
            }
            else
            {
                UnitHolyPrismHoly =
                    NearbyUnFriendlyUnits.OrderByDescending(unit => unit.HealthPercent).FirstOrDefault(
                        unit =>
                        BasicCheck(unit) &&
                        unit.HealthPercent <= THSettings.Instance.HolyPrismEnemyHP &&
                        FacingOverride(unit) &&
                        !InvulnerableSpell(unit) &&
                        Attackable(unit, 40));
            }

            return BasicCheck(UnitHolyPrismHoly);
        }

        private static double CountUnitHolyPrism(WoWUnit unitCenter)
        {
            return FarFriendlyPlayers.Count(
                unit =>
                BasicCheck(unit) &&
                unitCenter.Location.Distance(unit.Location) <= 15 &&
                HealWeight(unit) <= THSettings.Instance.HolyPrismEnemyHealHP);
        }

        private static WoWUnit UnitHolyPrismEnemyHeal;

        private static bool GetUnitHolyPrismEnemyHeal()
        {
            UnitHolyPrismEnemyHeal = null;
            UnitHolyPrismEnemyHeal = NearbyUnFriendlyUnits.OrderByDescending(CountUnitHolyPrism).FirstOrDefault(
                unit =>
                BasicCheck(unit) &&
                FacingOverride(unit) &&
                !InvulnerableSpell(unit) &&
                CountUnitHolyPrism(unit) >= THSettings.Instance.HolyPrismEnemyHealNumber &&
                unit.CurrentTarget != null &&
                FarFriendlyUnits.Contains(unit.CurrentTarget) &&
                Attackable(unit, 40));
            return BasicCheck(UnitHolyPrismEnemyHeal);
        }

        private static double CountUnitHolyPrismFriendDPS(WoWUnit unitCenter)
        {
            return NearbyUnFriendlyUnits.Count(
                unit =>
                BasicCheck(unit) &&
                !unit.IsPet &&
                !DebuffCCBreakonDamage(unit) &&
                unitCenter.Location.Distance(unit.Location) <= 15);
        }

        private static WoWUnit UnitHolyPrismFriendDPS;

        private static bool GetUnitHolyPrismFriendDPS()
        {
            UnitHolyPrismFriendDPS = null;
            UnitHolyPrismFriendDPS = NearbyFriendlyUnits.OrderByDescending(CountUnitHolyPrismFriendDPS)
                                                        .ThenByDescending(HealWeight)
                                                        .FirstOrDefault(
                                                            unit =>
                                                            BasicCheck(unit) &&
                                                            CountUnitHolyPrismFriendDPS(unit) >=
                                                            THSettings.Instance.HolyPrismFriendDPSNumber &&
                                                            Healable(unit));
            return BasicCheck(UnitHolyPrismFriendDPS);
        }

        private static Composite HolyPrism()
        {
            return new PrioritySelector(
                new Decorator(
                    ret =>
                    THSettings.Instance.HolyPrismFriend &&
                    //SSpellManager.HasSpell("Holy Prism") &&
                    ////!Me.Mounted &&
                    HealWeightUnitHeal <= THSettings.Instance.HolyPrismFriendHP &&
                    UnitHeal.Combat &&
                    CanCastCheck("Holy Prism"),
                    new Action(delegate { CastSpell("Holy Prism", UnitHeal, "HolyPrismFriend"); })),
                new Decorator(
                    ret =>
                    THSettings.Instance.HolyPrismEnemyHeal &&
                    //SSpellManager.HasSpell("Holy Prism") &&
                    ////!Me.Mounted &&
                    Me.Combat &&
                    GetUnitHolyPrismEnemyHeal() &&
                    CanCastCheck("Holy Prism"),
                    new Action(delegate
                        {
                            SafelyFacingTarget(UnitHolyPrismEnemyHeal);
                            CastSpell("Holy Prism", UnitHolyPrismEnemyHeal, "HolyPrismEnemyHeal");
                        })),
                new Decorator(
                    ret =>
                    THSettings.Instance.HolyPrismFriendDPS &&
                    //SSpellManager.HasSpell("Holy Prism") &&
                    ////!Me.Mounted &&
                    Me.Combat &&
                    GetUnitHolyPrismFriendDPS() &&
                    CanCastCheck("Holy Prism"),
                    new Action(delegate { CastSpell("Holy Prism", UnitHolyPrismFriendDPS, "HolyPrismFriendDPS"); })),
                new Decorator(
                    ret =>
                    THSettings.Instance.HolyPrismEnemy &&
                    //SSpellManager.HasSpell("Holy Prism") &&
                    Me.Specialization != WoWSpec.PaladinHoly &&
                    ////!Me.Mounted &&
                    CurrentTargetAttackable(40) &&
                    !Me.CurrentTarget.IsPet &&
                    FacingOverride(Me.CurrentTarget) &&
                    !InvulnerableSpell(Me.CurrentTarget) &&
                    Me.CurrentTarget.HealthPercent <= THSettings.Instance.HolyPrismEnemyHP &&
                    CanCastCheck("Holy Prism"),
                    new Action(delegate
                        {
                            SafelyFacingTarget(Me.CurrentTarget);
                            CastSpell("Holy Prism", Me.CurrentTarget, "HolyPrismEnemy");
                        })),
                new Decorator(
                    ret =>
                    THSettings.Instance.HolyPrismEnemy &&
                    //SSpellManager.HasSpell("Holy Prism") &&
                    Me.Specialization == WoWSpec.PaladinHoly &&
                    ////!Me.Mounted &&
                    GetUnitHolyPrismHoly() &&
                    CanCastCheck("Holy Prism"),
                    new Action(delegate
                        {
                            SafelyFacingTarget(UnitHolyPrismHoly);
                            CastSpell("Holy Prism", UnitHolyPrismHoly, "UnitHolyPrismHoly");
                        }))
                );
        }

        #endregion

        #region HolyRadiance

        private static WoWPlayer PlayerHolyRadiance;

        private static int TotalUnitHolyRadiance;

        private static double CountUnitHolyRadiance(WoWUnit unitCenter)
        {
            TotalUnitHolyRadiance = 0;

            foreach (var unit in NearbyFriendlyPlayers)
            {
                if (!BasicCheck(unit) ||
                    !(unitCenter.Location.Distance(unit.Location) <= 10) ||
                    HealWeight(unit) > THSettings.Instance.HolyRadianceHP)
                {
                    continue;
                }

                if (DebuffDoNotHeal(unit))
                {
                    TotalUnitHolyRadiance = TotalUnitHolyRadiance - 1000;
                }

                TotalUnitHolyRadiance = TotalUnitHolyRadiance + 1;
            }

            return TotalUnitHolyRadiance;

            //return NearbyFriendlyPlayers.Count(
            //    unit =>
            //    BasicCheck(unit) &&
            //    unitCenter.Location.Distance(unit.Location) <= 10 &&
            //    HealWeight(unit) <= THSettings.Instance.HolyRadianceHP);
        }

        private static bool GetPlayerHolyRadiance()
        {
            //using (StyxWoW.Memory.AcquireFrame())
            {
                PlayerHolyRadiance = null;
                PlayerHolyRadiance =
                    NearbyFriendlyPlayers.OrderByDescending(CountUnitHolyRadiance).FirstOrDefault(
                        unit =>
                        BasicCheck(unit) &&
                        CountUnitHolyRadiance(unit) >= THSettings.Instance.HolyRadianceNumber &&
                        Healable(unit));
                return BasicCheck(PlayerHolyRadiance);
            }
        }

        private static Composite HolyRadiance()
        {
            return new Decorator(
                ret =>
                THSettings.Instance.HolyRadiance &&
                //SSpellManager.HasSpell("Holy Radiance") &&
                PlayerHolyPower < 3 &&
                !MeHasAura(90174) &&
                !IsMoving(Me) &&
                GetPlayerHolyRadiance() &&
                !HoldonDivinePleaHP() &&
                CanCastCheck("Holy Radiance"),
                new Action(delegate { CastSpell("Holy Radiance", PlayerHolyRadiance, "HolyRadiance"); }));
        }

        #endregion

        #region HolyShock

        private static Composite HolyShock()
        {
            return new Decorator(
                ret =>
                //_lastCastSpell != "Holy Shock" &&
                //SSpellManager.HasSpell("Holy Shock") &&
                ////!Me.Mounted &&
                (InArena || InBattleground || InInstance || InRaid || Me.Combat) &&
                !HasOneAura(Me,
                            new HashSet<string>
                                {
                                    "Drink",
                                    "Food",
                                    "Arena Preparation",
                                    "Preparation",
                                }) &&
                //!MeHasAura("Drink") &&
                //!MeHasAura("Food") &&
                //!HasAuraArenaPreparation &&
                //!HasAuraPreparation &&
                //Don't waste a Holy Shock when you have Holy Avenger
                (!MeHasAura("Holy Avenger") ||
                 MeHasAura("Holy Avenger") &&
                 PlayerHolyPower < 3) &&
                (PlayerHolyPower < 5 ||
                 HealWeightUnitHeal <= THSettings.Instance.DoNotHealAbove) &&
                //(InArena || InBattleground || Me.Combat ||
                // Me.ManaPercent >= THSettings.Instance.ManaforDPS &&
                // (InDungeon || InRaid)) &&
                Healable(UnitHeal) &&
                //!Blacklist.Contains(UnitHeal.Guid, BlacklistFlags.All) &&
                CanCastCheck("Holy Shock"),
                new Action(delegate { CastSpell("Holy Shock", UnitHeal); }));
        }

        #endregion

        #region HolyWrath

        private static Composite HolyWrath()
        {
            return new Decorator(
                ret =>
                THSettings.Instance.HolyWrath &&
                //SSpellManager.HasSpell("Holy Wrath") &&
                ////!Me.Mounted &&
                (CurrentTargetAttackable(10) &&
                 FacingOverride(Me.CurrentTarget) &&
                 !InvulnerableSpell(Me.CurrentTarget) ||
                 CountEnemyNeary(Me, 10) > 0) &&
                CanCastCheck("Holy Wrath"),
                new Action(delegate
                    {
                        SafelyFacingTarget(Me.CurrentTarget);
                        CastSpell("Holy Wrath", Me.CurrentTarget);
                    })
                );
        }

        #endregion

        #region Hotkeys

        private static WoWUnit HotkeyTargettoUnit(int HotkeyTarget)
        {
            switch (HotkeyTarget)
            {
                case 1:
                    if (BasicCheck(Me.CurrentTarget) && IsEnemy(Me.CurrentTarget))
                    {
                        return Me.CurrentTarget;
                    }
                    break;
                case 2:
                    if (BasicCheck(Me.FocusedUnit) && IsEnemy(Me.FocusedUnit))
                    {
                        return Me.FocusedUnit;
                    }
                    break;
                case 3:
                    return Me;
            }
            return null;
        }

        private static bool HotKeyTargetValidate(int HotkeyTarget)
        {
            if (HotkeyTargettoUnit(HotkeyTarget) != null)
            {
                return true;
            }
            return false;
        }

        private static string HotKeySpelltoName(int HotkeySpell)
        {
            switch (HotkeySpell)
            {
                case 1:
                    return "Blinding Light";
                case 2:
                    return "Divine Shield";
                case 3:
                    return "Hammer of Justice";
                case 4:
                    return "Hand of Freedom";
                case 5:
                    return "Hand of Protection";
                case 6:
                    return "Hand of Purity";
                case 7:
                    return "Hand of Sacrifice";
                case 8:
                    return "Hand of Salvation";
                case 9:
                    return "Seal of Insight";
                case 10:
                    return "Seal of Justice";
                case 11:
                    return "Seal of Righteousness";
                case 12:
                    return "Seal of Truth";
                case 13:
                    return "Turn Evil";
                case 14:
                    return "Repentance";
            }
            return "None Exist Spell";
        }

        private static bool HotKeySpellValidate(int HotkeySpell)
        {
            if (//SSpellManager.HasSpell(HotKeySpelltoName(HotkeySpell)) &&
                SpellManager.Spells[HotKeySpelltoName(HotkeySpell)].CooldownTimeLeft.TotalMilliseconds < 400)
            {
                return true;
            }

            return false;
        }


        private static Composite Hotkey1()
        {
            return new Action(delegate
                {
                    if (THSettings.Instance.Hotkey1Target != 0 &&
                        THSettings.Instance.Hotkey1Key != 0 &&
                        THSettings.Instance.Hotkey1Spell != 0 &&
                        (THSettings.Instance.Hotkey1Mod == 0 ||
                         THSettings.Instance.Hotkey1Mod != 0 &&
                         GetAsyncKeyState(IndexToKeysMod(THSettings.Instance.Hotkey1Mod)) < 0) &&
                        GetAsyncKeyState(IndexToKeys(THSettings.Instance.Hotkey1Key)) < 0 &&
                        HotKeyTargetValidate(THSettings.Instance.Hotkey1Target) &&
                        HotKeySpellValidate(THSettings.Instance.Hotkey1Spell))
                    {
                        SafelyFacingTarget(HotkeyTargettoUnit(THSettings.Instance.Hotkey1Target));
                        SpellManager.StopCasting();
                        CastSpell(HotKeySpelltoName(THSettings.Instance.Hotkey1Spell),
                                  HotkeyTargettoUnit(THSettings.Instance.Hotkey1Target),
                                  "Hotkey: Cast " + HotKeySpelltoName(THSettings.Instance.Hotkey1Spell) + " on " +
                                  SafeName(HotkeyTargettoUnit(THSettings.Instance.Hotkey1Target)));
                    }
                    return RunStatus.Failure;
                });
        }

        private static Composite Hotkey2()
        {
            return new Action(delegate
                {
                    if (THSettings.Instance.Hotkey2Target != 0 &&
                        THSettings.Instance.Hotkey2Key != 0 &&
                        THSettings.Instance.Hotkey2Spell != 0 &&
                        (THSettings.Instance.Hotkey2Mod == 0 ||
                         THSettings.Instance.Hotkey2Mod != 0 &&
                         GetAsyncKeyState(IndexToKeysMod(THSettings.Instance.Hotkey2Mod)) < 0) &&
                        GetAsyncKeyState(IndexToKeys(THSettings.Instance.Hotkey2Key)) < 0 &&
                        HotKeyTargetValidate(THSettings.Instance.Hotkey2Target) &&
                        HotKeySpellValidate(THSettings.Instance.Hotkey2Spell))
                    {
                        SafelyFacingTarget(HotkeyTargettoUnit(THSettings.Instance.Hotkey2Target));
                        SpellManager.StopCasting();
                        CastSpell(HotKeySpelltoName(THSettings.Instance.Hotkey2Spell),
                                  HotkeyTargettoUnit(THSettings.Instance.Hotkey2Target),
                                  "Hotkey: Cast " + HotKeySpelltoName(THSettings.Instance.Hotkey2Spell) + " on " +
                                  SafeName(HotkeyTargettoUnit(THSettings.Instance.Hotkey2Target)));
                    }
                    return RunStatus.Failure;
                });
        }

        private static Composite Hotkey3()
        {
            return new Action(delegate
                {
                    if (THSettings.Instance.Hotkey3Target != 0 &&
                        THSettings.Instance.Hotkey3Key != 0 &&
                        THSettings.Instance.Hotkey3Spell != 0 &&
                        (THSettings.Instance.Hotkey3Mod == 0 ||
                         THSettings.Instance.Hotkey3Mod != 0 &&
                         GetAsyncKeyState(IndexToKeysMod(THSettings.Instance.Hotkey3Mod)) < 0) &&
                        GetAsyncKeyState(IndexToKeys(THSettings.Instance.Hotkey3Key)) < 0 &&
                        HotKeyTargetValidate(THSettings.Instance.Hotkey3Target) &&
                        HotKeySpellValidate(THSettings.Instance.Hotkey3Spell))
                    {
                        SafelyFacingTarget(HotkeyTargettoUnit(THSettings.Instance.Hotkey3Target));
                        SpellManager.StopCasting();
                        CastSpell(HotKeySpelltoName(THSettings.Instance.Hotkey3Spell),
                                  HotkeyTargettoUnit(THSettings.Instance.Hotkey3Target),
                                  "Hotkey: Cast " + HotKeySpelltoName(THSettings.Instance.Hotkey3Spell) + " on " +
                                  SafeName(HotkeyTargettoUnit(THSettings.Instance.Hotkey3Target)));
                    }
                    return RunStatus.Failure;
                });
        }

        private static Composite Hotkey4()
        {
            return new Action(delegate
                {
                    if (THSettings.Instance.Hotkey4Target != 0 &&
                        THSettings.Instance.Hotkey4Key != 0 &&
                        THSettings.Instance.Hotkey4Spell != 0 &&
                        (THSettings.Instance.Hotkey4Mod == 0 ||
                         THSettings.Instance.Hotkey4Mod != 0 &&
                         GetAsyncKeyState(IndexToKeysMod(THSettings.Instance.Hotkey4Mod)) < 0) &&
                        GetAsyncKeyState(IndexToKeys(THSettings.Instance.Hotkey4Key)) < 0 &&
                        HotKeyTargetValidate(THSettings.Instance.Hotkey4Target) &&
                        HotKeySpellValidate(THSettings.Instance.Hotkey4Spell))
                    {
                        SafelyFacingTarget(HotkeyTargettoUnit(THSettings.Instance.Hotkey4Target));
                        SpellManager.StopCasting();
                        CastSpell(HotKeySpelltoName(THSettings.Instance.Hotkey4Spell),
                                  HotkeyTargettoUnit(THSettings.Instance.Hotkey4Target),
                                  "Hotkey: Cast " + HotKeySpelltoName(THSettings.Instance.Hotkey4Spell) + " on " +
                                  SafeName(HotkeyTargettoUnit(THSettings.Instance.Hotkey4Target)));
                    }
                    return RunStatus.Failure;
                });
        }

        private static Composite Hotkey5()
        {
            return new Action(delegate
                {
                    if (THSettings.Instance.Hotkey5Target != 0 &&
                        THSettings.Instance.Hotkey5Key != 0 &&
                        THSettings.Instance.Hotkey5Spell != 0 &&
                        (THSettings.Instance.Hotkey5Mod == 0 ||
                         THSettings.Instance.Hotkey5Mod != 0 &&
                         GetAsyncKeyState(IndexToKeysMod(THSettings.Instance.Hotkey5Mod)) < 0) &&
                        GetAsyncKeyState(IndexToKeys(THSettings.Instance.Hotkey5Key)) < 0 &&
                        HotKeyTargetValidate(THSettings.Instance.Hotkey5Target) &&
                        HotKeySpellValidate(THSettings.Instance.Hotkey5Spell))
                    {
                        SafelyFacingTarget(HotkeyTargettoUnit(THSettings.Instance.Hotkey5Target));
                        SpellManager.StopCasting();
                        CastSpell(HotKeySpelltoName(THSettings.Instance.Hotkey5Spell),
                                  HotkeyTargettoUnit(THSettings.Instance.Hotkey5Target),
                                  "Hotkey: Cast " + HotKeySpelltoName(THSettings.Instance.Hotkey5Spell) + " on " +
                                  SafeName(HotkeyTargettoUnit(THSettings.Instance.Hotkey5Target)));
                    }
                    return RunStatus.Failure;
                });
        }

        #endregion

        #region InquisitionMe

        private static Composite InquisitionMe()
        {
            return new Decorator(
                ret =>
                //SSpellManager.HasSpell("Inquisition") &&
                ////!Me.Mounted &&
                CurrentTargetAttackable(40) &&
                (PlayerHolyPower >= THSettings.Instance.InquisitionHolyPower ||
                 MeHasAura(90174)) &&
                MyAuraTimeLeft(84963, Me) <= 5000 && //Inquisition - 84963
                CanCastCheck("Inquisition"),
                new Action(delegate { CastSpell("Inquisition", Me); }));
        }

        #endregion

        #region InquisitionMeTopUp

        private static Composite InquisitionMeTopUp()
        {
            return new Decorator(
                ret =>
                //SSpellManager.HasSpell("Inquisition") &&
                ////!Me.Mounted &&
                (PlayerHolyPower >= THSettings.Instance.InquisitionHolyPower ||
                 MeHasAura(90174)) &&
                MyAuraTimeLeft("Inquisition", Me) < 1000 &&
                CanCastCheck("Inquisition"),
                new Action(delegate { CastSpell("Inquisition", Me); })
                );
        }

        #endregion

        #region Interrupt

        private static DateTime LastInterrupt;

        #endregion

        #region Judgement Selfless Healer

        private static WoWUnit UnitJudgmentSelflessHealerHoly;

        private static bool GetUnitJudgmentSelflessHealerHoly()
        {
            UnitJudgmentSelflessHealerHoly = null;

            UnitJudgmentSelflessHealerHoly = NearbyUnFriendlyUnits.OrderBy(HealWeight).FirstOrDefault(
                unit => BasicCheck(unit) &&
                        (Me.GetAuraById(114250) == null ||
                         Me.GetAuraById(114250) != null &&
                         Me.GetAuraById(114250).StackCount < 3 ||
                         Me.GetAuraById(114250) != null &&
                         Me.GetAuraById(114250).TimeLeft.TotalMilliseconds < 6000) &&
                        unit.Combat &&
                        FarFriendlyUnits.Contains(unit.CurrentTarget) &&
                        !InvulnerableSpell(unit) &&
                        Attackable(unit, 30 + _bonusJudgementRange));

            return BasicCheck(UnitJudgmentSelflessHealerHoly);
        }

        private static Composite JudgmentSelflessHealerHoly()
        {
            return new PrioritySelector(
                new Decorator(
                    ret =>
                    //THSettings.Instance.Judgment &&
                    //SSpellManager.HasSpell("Selfless Healer") &&
                    //SSpellManager.HasSpell("Judgment") &&
                    ////!Me.Mounted &&
                    GetUnitJudgmentSelflessHealerHoly() &&
                    CanCastCheck("Judgment"),
                    new Action(delegate
                        {
                            CastSpell("Judgment", UnitJudgmentSelflessHealerHoly);
                            UnitJudgmentSelflessHealerHoly = null;
                        })));
        }

        #endregion

        #region Judgement

        private static WoWUnit UnitDoubleJeopardy;

        private static bool GetUnitDoubleJeopardy()
        {
            UnitDoubleJeopardy = null;
            //using (StyxWoW.Memory.AcquireFrame())
            {
                UnitDoubleJeopardy = NearbyUnFriendlyUnits.OrderBy(unit => MyAuraTimeLeft(31803, unit))
                                                          .FirstOrDefault(
                                                              unit =>
                                                              BasicCheck(unit) &&
                                                              Me.Combat &&
                                                              (unit.Combat &&
                                                               FarFriendlyUnits.Contains(unit.CurrentTarget) ||
                                                               IsDummy(unit)) &&
                                                              !InvulnerableSpell(unit) &&
                                                              Attackable(unit, 30 + _bonusJudgementRange));
            }

            return BasicCheck(UnitDoubleJeopardy);
        }

        private static Composite JudgementRet()
        {
            return new PrioritySelector(
                new Decorator(
                    ret =>
                    //SSpellManager.HasSpell("Judgment") &&
                    (!HasGlyph.Contains("54922") || //Glyph of Double Jeopardy - 
                     InBattleground ||
                     InArena) &&
                    ////!Me.Mounted &&
                    CurrentTargetAttackable(30 + _bonusJudgementRange) &&
                    !InvulnerableSpell(Me.CurrentTarget) &&
                    (PlayerHolyPower < Me.MaxHolyPower || GetDistance(Me.CurrentTarget) > 5) &&
                    CanCastCheck("Judgment"),
                    new Action(delegate { CastSpell("Judgment", Me.CurrentTarget, "JudgementRet"); })),
                new Decorator(
                    ret =>
                    //SSpellManager.HasSpell("Judgment") &&
                    HasGlyph.Contains("54922") && //Glyph of Double Jeopardy - 
                    //Me.GetAuraById(121027) != null && //Glyph of Double Jeopardy
                    ////!Me.Mounted &&
                    (PlayerHolyPower < Me.MaxHolyPower) &&
                    GetUnitDoubleJeopardy() &&
                    UnitDoubleJeopardy != null &&
                    UnitDoubleJeopardy.IsValid &&
                    CanCastCheck("Judgment"),
                    new Action(
                        delegate { CastSpell("Judgment", UnitDoubleJeopardy, "JudgementRet: UnitDoubleJeopardy"); })
                    ));
        }

        private static Composite JudgementProt()
        {
            return new PrioritySelector(
                new Decorator(
                    ret =>
                    //SSpellManager.HasSpell("Judgment") &&
                    (!HasGlyph.Contains("54922") || //Glyph of Double Jeopardy - 
                     InBattleground ||
                     InArena) &&
                    ////!Me.Mounted &&
                    CurrentTargetAttackable(30 + _bonusJudgementRange) &&
                    !InvulnerableSpell(Me.CurrentTarget) &&
                    (!THSettings.Instance.ShieldofRighterous ||
                     PlayerHolyPower < Me.MaxHolyPower ||
                     GetDistance(Me.CurrentTarget) > 5) &&
                    CanCastCheck("Judgment"),
                    new Action(delegate { CastSpell("Judgment", Me.CurrentTarget, "JudgementRet"); })),
                new Decorator(
                    ret =>
                    //SSpellManager.HasSpell("Judgment") &&
                    HasGlyph.Contains("54922") && //Glyph of Double Jeopardy - 
                    //Me.GetAuraById(121027) != null && //Glyph of Double Jeopardy
                    ////!Me.Mounted &&
                    (!THSettings.Instance.ShieldofRighterous ||
                     PlayerHolyPower < Me.MaxHolyPower) &&
                    GetUnitDoubleJeopardy() &&
                    UnitDoubleJeopardy != null &&
                    UnitDoubleJeopardy.IsValid &&
                    CanCastCheck("Judgment"),
                    new Action(
                        delegate { CastSpell("Judgment", UnitDoubleJeopardy, "JudgementRet: UnitDoubleJeopardy"); })
                    ));
        }

        #endregion

        #region JudgementRangeRetPvP

        private static Composite JudgementRangeRetPvP()
        {
            return new Decorator(
                ret =>
                THSettings.Instance.Judgment &&
                //SSpellManager.HasSpell("Judgment") &&
                ////!Me.Mounted &&
                CurrentTargetAttackable(30 + _bonusJudgementRange) &&
                Me.CurrentTarget.IsPlayer &&
                (//SSpellManager.HasSpell("Long Arm of the Law") &&
                 !MeHasAura(87173) &&
                 GetDistance(Me.CurrentTarget) > 5 ||
                 //SSpellManager.HasSpell("Burden of Guilt") &&
                 !DebuffRootorSnare(Me.CurrentTarget)) &&
                CanCastCheck("Judgment"),
                new Action(delegate { CastSpell("Judgment", Me.CurrentTarget); })
                );
        }

        #endregion

        #region JudgementRangeRetPvE

        private static Composite JudgementRangeRetPvE()
        {
            return new Decorator(
                ret =>
                THSettings.Instance.Judgment &&
                //SSpellManager.HasSpell("Judgment") &&
                (InDungeon ||
                 InRaid) &&
                ////!Me.Mounted &&
                !MeHasAura("Hand of Protection") &&
                CurrentTargetAttackable(30 + _bonusJudgementRange) &&
                (//SSpellManager.HasSpell("Long Arm of the Law") &&
                 GetDistance(Me.CurrentTarget) > 8) &&
                CanCastCheck("Judgment"),
                new Action(delegate { CastSpell("Judgment", Me.CurrentTarget); })
                );
        }

        #endregion

        #region LayonHands

        private static Composite LayonHands()
        {
            return new PrioritySelector(
                new Decorator(
                    ret =>
                    THSettings.Instance.LayonHands &&
                    //SSpellManager.HasSpell("Lay on Hands") &&
                    ////!Me.Mounted &&
                    Me.Combat &&
                    !InArena &&
                    !Me.IsFFAPvPFlagged &&
                    !MeHasAura("Forbearance") &&
                    HealWeightMe <= THSettings.Instance.LayonHandsHP &&
                    CanCastCheck("Lay on Hands", true) &&
                    ////SSpellManager.HasSpell("Divine Shield") && Don't Care because Lay On Hands at 16 and Divine Shield at 20
                    SpellManager.Spells["Divine Shield"].CooldownTimeLeft.TotalMilliseconds > MyLatency,
                    new Action(delegate
                        {
                            CastSpell("Lay on Hands", Me, "LayonHands");
                            return RunStatus.Failure;
                        })),
                new Decorator(
                    ret =>
                    THSettings.Instance.LayonHands &&
                    //SSpellManager.HasSpell("Lay on Hands") &&
                    ////!Me.Mounted &&
                    Me.Combat &&
                    !InArena &&
                    !Me.IsFFAPvPFlagged &&
                    HealWeightUnitHeal <= THSettings.Instance.LayonHandsHP &&
                    !UnitHeal.HasAura("Forbearance") &&
                    (HasOneAura(UnitHeal,
                                new HashSet<string>
                                    {
                                        "Alliance Flag",
                                        "Horde Flag",
                                        "Netherstorm Flag",
                                        "Orb of Power",
                                    }) ||
                     Me.CurrentTarget == UnitHeal ||
                     Me.FocusedUnit == UnitHeal ||
                     InRaid ||
                     InDungeon) &&
                    CanCastCheck("Lay on Hands", true),
                    new Action(delegate
                        {
                            CastSpell("Lay on Hands", UnitHeal, "LayonHands");
                            return RunStatus.Failure;
                        }))
                );
        }

        #endregion

        #region LightHammer

        private static WoWUnit PlayerLightsHammer;

        private static double CountUnitLightsHammer(WoWUnit unitCenter)
        {
            return
                NearbyFriendlyPlayers.Count(
                    unit =>
                    BasicCheck(unit) &&
                    unitCenter.Location.Distance(unit.Location) <= 10 &&
                    HealWeight(unit) <= THSettings.Instance.LightsHammerFriendHP);
        }

        private static bool GetPlayerLightsHammer()
        {
            PlayerLightsHammer = null;

            PlayerLightsHammer = NearbyFriendlyPlayers.OrderByDescending(CountUnitLightsHammer).FirstOrDefault(
                unit =>
                BasicCheck(unit) &&
                GetDistance(unit) < 30 &&
                CountUnitLightsHammer(unit) >= THSettings.Instance.LightsHammerFriendNumber &&
                Healable(unit));

            return BasicCheck(PlayerLightsHammer);
        }

        private static WoWUnit EnemyLightsHammer;

        private static bool GetEnemyLightsHammer()
        {
            EnemyLightsHammer = null;

            EnemyLightsHammer = NearbyFriendlyUnits.OrderByDescending(unit => CountEnemyNeary(unit, 10)).FirstOrDefault(
                unit =>
                BasicCheck(unit) &&
                CountEnemyNeary(unit, 10) >= THSettings.Instance.LightsHammerEnemyNumber &&
                Attackable(unit, 30));

            return BasicCheck(EnemyLightsHammer);
        }

        private static DateTime LastClickRemoteLocation;

        private static Composite LightHammer()
        {
            return new PrioritySelector(
                new Decorator(
                    ret =>
                    THSettings.Instance.LightsHammerFriend &&
                    //SSpellManager.HasSpell("Light's Hammer") &&
                    ////!Me.Mounted &&
                    Me.Combat &&
                    GetPlayerLightsHammer() &&
                    CanCastCheck("Light's Hammer"),
                    new Action(delegate
                        {
                            CastSpell("Light's Hammer", PlayerLightsHammer, "LightsHammerFriend");

                            LastClickRemoteLocation = DateTime.Now + TimeSpan.FromMilliseconds(300);
                            while (LastClickRemoteLocation > DateTime.Now)
                            {
                                SpellManager.ClickRemoteLocation(PlayerLightsHammer.Location);
                            }
                        })),
                new Decorator(
                    ret =>
                    THSettings.Instance.LightsHammerEnemy &&
                    //SSpellManager.HasSpell("Light's Hammer") &&
                    ////!Me.Mounted &&
                    Me.Combat &&
                    CurrentTargetAttackable(30) &&
                    Me.Specialization != WoWSpec.PaladinHoly &&
                    CountEnemyNeary(Me.CurrentTarget, 10) >= THSettings.Instance.LightsHammerEnemyNumber &&
                    CanCastCheck("Light's Hammer"),
                    new Action(delegate
                        {
                            CastSpell("Light's Hammer", Me.CurrentTarget, "LightsHammerEnemy Ret/Prot");

                            LastClickRemoteLocation = DateTime.Now + TimeSpan.FromMilliseconds(300);
                            while (LastClickRemoteLocation > DateTime.Now)
                            {
                                SpellManager.ClickRemoteLocation(Me.CurrentTarget.Location);
                            }
                        })),
                new Decorator(
                    ret =>
                    THSettings.Instance.LightsHammerEnemy &&
                    //SSpellManager.HasSpell("Light's Hammer") &&
                    ////!Me.Mounted &&
                    Me.Combat &&
                    CurrentTargetAttackable(30) &&
                    Me.Specialization == WoWSpec.PaladinHoly &&
                    GetEnemyLightsHammer() &&
                    CanCastCheck("Light's Hammer"),
                    new Action(delegate
                        {
                            CastSpell("Light's Hammer", EnemyLightsHammer, "LightsHammerEnemy Holy");

                            LastClickRemoteLocation = DateTime.Now + TimeSpan.FromMilliseconds(300);
                            while (LastClickRemoteLocation > DateTime.Now)
                            {
                                SpellManager.ClickRemoteLocation(EnemyLightsHammer.Location);
                            }
                        }))
                );
        }

        #endregion

        #region LightofDawn

        private static int TotalUnitHolyRadianceLightofDawn;

        private static double CountUnitLightofDawn()
        {
            TotalUnitHolyRadianceLightofDawn = 0;

            foreach (var unit in NearbyFriendlyPlayers)
            {
                if (!BasicCheck(unit) ||
                    unit.Distance > 30 ||
                    HealWeight(unit) > THSettings.Instance.LightofDawnHP)
                {
                    continue;
                }

                if (DebuffDoNotHeal(unit))
                {
                    TotalUnitHolyRadianceLightofDawn = TotalUnitHolyRadianceLightofDawn - 1000;
                }

                TotalUnitHolyRadianceLightofDawn = TotalUnitHolyRadianceLightofDawn + 1;
            }

            return TotalUnitHolyRadianceLightofDawn;

            //return
            //    NearbyFriendlyPlayers.Where(
            //        unit => BasicCheck(unit) &&
            //                unit.IsValid &&
            //                unitCenter.Location.Distance(unit.Location) <= 30 &&
            //                HealWeight(unit) < THSettings.Instance.LightofDawnHP).Aggregate
            //        <WoWPlayer, double>(0, (current, unit) => current + 1);
        }

        private static Composite LightofDawn()
        {
            return new Decorator(
                ret =>
                THSettings.Instance.LightofDawn &&
                //SSpellManager.HasSpell("Light of Dawn") &&
                (PlayerHolyPower >= 3 || MeHasAura(90174)) &&
                (CountUnitLightofDawn() >= THSettings.Instance.LightofDawnNumber ||
                 CountUnitLightofDawn() > 0 &&
                 MeHasAura(90174) &&
                 MyAuraTimeLeft(90174, Me) < 3000) &&
                CanCastCheck("Light of Dawn"),
                new Action(delegate { CastSpell("Light of Dawn", Me); }));
        }

        #endregion

        #region PlayerHolyPower

        private static double PlayerHolyPower
        {
            get
            {
                //using (StyxWoW.Memory.AcquireFrame())
                //{
                if (Me.IsCasting && Me.CastingSpell.Name == "Holy Radiance")
                {
                    return Me.CurrentHolyPower + 1;
                }
                return Me.CurrentHolyPower;

                //}

                //try
                //{
                //    //using (StyxWoW.Memory.AcquireFrame())
                //    {
                //        var currentholypower =
                //            Lua.GetReturnVal<int>("return UnitPower(\"player\", SPELL_POWER_HOLY_POWER);", 0);

                //        //var currentholypower = Me.CurrentHolyPower;

                //        if (Me.IsCasting && Me.CastingSpell.Name == "Holy Radiance")
                //        {
                //            return currentholypower + 1;
                //        }
                //        return currentholypower;
                //    }
                //}
                //catch
                //{
                //    Logging.Write(" Lua Failed in PlayerHolyPower");
                //    return 0;
                //}
            }
        }

        #endregion PlayerHolyPower

        #region Rebuke

        private static WoWUnit UnitRebuke;

        private static bool GetUnitRebuke()
        {
            UnitRebuke = null;

            if (InBattleground || InArena)
            {
                UnitRebuke = NearbyUnFriendlyPlayers.FirstOrDefault(
                    unit => BasicCheck(unit) &&
                            (THSettings.Instance.InterruptAll ||
                             THSettings.Instance.InterruptTarget &&
                             Me.CurrentTarget != null &&
                             unit == Me.CurrentTarget ||
                             THSettings.Instance.InterruptFocus &&
                             Me.FocusedUnit != null &&
                             unit == Me.FocusedUnit) &&
                            FacingOverride(unit) &&
                            InterruptCheck(unit, THSettings.Instance.RebukeMs + MyLatency + 1000, false) &&
                            Attackable(unit, 5));
            }
                //PvE Search
            else
            {
                UnitRebuke = NearbyUnFriendlyUnits.FirstOrDefault(
                    unit => BasicCheck(unit) &&
                            (THSettings.Instance.InterruptAll ||
                             THSettings.Instance.InterruptTarget &&
                             Me.CurrentTarget != null &&
                             unit == Me.CurrentTarget ||
                             THSettings.Instance.InterruptFocus &&
                             Me.FocusedUnit != null &&
                             unit == Me.FocusedUnit) &&
                            unit.Combat &&
                            FacingOverride(unit) &&
                            FarFriendlyUnits.Contains(unit.CurrentTarget) &&
                            InterruptCheck(unit, THSettings.Instance.RebukeMs + MyLatency + 1000, false) &&
                            Attackable(unit, 5));
            }

            return BasicCheck(UnitRebuke);
        }

        private static void RebukeVoid()
        {
            if (THSettings.Instance.Rebuke &&
                //SSpellManager.HasSpell("Rebuke") &&
                LastInterrupt < DateTime.Now &&
                GetUnitRebuke() &&
                CanCastCheck("Rebuke", true))
            {
                if (Me.IsCasting || Me.IsChanneling)
                {
                    SpellManager.StopCasting();
                }
                SafelyFacingTarget(UnitRebuke);

                while (UnitRebuke.CurrentCastTimeLeft.TotalMilliseconds >
                       THSettings.Instance.RebukeMs + MyLatency)
                {
                    Logging.Write("Waiting for Rebuke");
                }

                if (UnitRebuke.IsCasting || UnitRebuke.IsChanneling)
                {
                    CastSpell("Rebuke", UnitRebuke, "Rebuke");
                    LastInterrupt = DateTime.Now + TimeSpan.FromMilliseconds(1500);
                }
            }
        }

        #endregion

        #region Reckoning

        private static WoWUnit UnitReckoning;

        private static bool GetUnitReckoning()
        {
            UnitReckoning = null;

            UnitReckoning = NearbyUnFriendlyUnits.OrderBy(DebuffDot).FirstOrDefault(
                unit => BasicCheck(unit) &&
                        (//SSpellManager.HasSpell("Holy Insight") ||
                         unit.IsPlayer) &&
                        !unit.Name.Contains("Mine Cart") &&
                        (unit.IsPet &&
                         unit.GotTarget &&
                         unit.CurrentTarget != Me ||
                         unit.IsPlayer &&
                         unit.Class == WoWClass.Rogue ||
                         unit.IsPlayer &&
                         unit.Class == WoWClass.Druid
                         && TalentSort(unit) == 1) &&
                        //!InvulnerableSpell(unit) &&
                        Attackable(unit, 30));

            return BasicCheck(UnitReckoning);
        }

        private static Composite ReckoningPvPComp()
        {
            return new Decorator(
                ret =>
                THSettings.Instance.AutoTaunt &&
                //SSpellManager.HasSpell("Reckoning") &&
                //LastCastSpell != "Holy Light" &&
                //LastCastSpell != "Divine Light" &&
                //LastCastSpell != "Flash of Light" &&
                //Me.Combat &&
                (InArena || InBattleground) &&
                GetUnitReckoning() &&
                CanCastCheck("Reckoning", true),
                new Action(
                    ret =>
                        {
                            CastSpell("Reckoning", UnitReckoning, "ReckoningPvPComp");
                            return RunStatus.Failure;
                        })
                );
        }

        private static WoWUnit UnitReckoningProtection;

        private static bool GetUnitReckoningProtection()
        {
            UnitReckoningProtection = null;
            //using (StyxWoW.Memory.AcquireFrame())
            {
                UnitReckoningProtection = NearbyUnFriendlyUnits.FirstOrDefault(
                    unit => BasicCheck(unit) &&
                            Me.Combat &&
                            (InDungeon || InRaid) &&
                            unit.Combat &&
                            !unit.Fleeing &&
                            !unit.IsTargetingMeOrPet &&
                            FarFriendlyUnits.Contains(unit.CurrentTarget) &&
                            !unit.CurrentTarget.HasAura("Vengeance") &&
                            unit.GetThreatInfoFor(unit.CurrentTarget).ThreatValue >= 90 &&
                            Attackable(unit, 30));

                return BasicCheck(UnitReckoningProtection);
            }
        }

        private static Composite ReckoningCompProtection()
        {
            return new Decorator(
                ret =>
                THSettings.Instance.AutoTaunt &&
                //SSpellManager.HasSpell("Reckoning") &&
                !Me.IsFlying &&
                GetUnitReckoningProtection() &&
                UnitReckoningProtection.IsValid &&
                CanCastCheck("Reckoning", true),
                new Action(delegate
                    {
                        CastSpell("Reckoning", UnitReckoningProtection);
                        return RunStatus.Failure;
                    })
                );
        }

        #endregion

        #region Repentance

        private static WoWUnit UnitFriendlyTargeting;
        private static WoWUnit UnitRepentance;

        private static bool IsTargetedByOurUnit(WoWUnit u)
        {
            UnitFriendlyTargeting = null;
            //using (StyxWoW.Memory.AcquireFrame())
            {
                UnitFriendlyTargeting = FarFriendlyUnits.FirstOrDefault(
                    unit => BasicCheck(unit) &&
                            unit != Me &&
                            unit.CurrentTarget == u);
            }

            return BasicCheck(UnitFriendlyTargeting);
        }

        private static bool GetUnitRepentance()
        {
            if (!THSettings.Instance.RepentanceCC)
            {
                return false;
            }

            UnitRepentance = null;
            if (//SSpellManager.HasSpell("Repentance"))
            {
                //using (StyxWoW.Memory.AcquireFrame())
                {
                    UnitRepentance =
                        NearbyUnFriendlyPlayers.OrderByDescending(TalentSortSimple).FirstOrDefault(
                            unit => BasicCheck(unit) &&
                                    unit.HealthPercent > 50 &&
                                    !HasOneAura(unit,
                                                new HashSet<string>
                                                    {
                                                        "Berserker Rage",
                                                        "Bear Form",
                                                        "Cat Form",
                                                        "Aquatic Form",
                                                        "Travel Form",
                                                        "Flight Form",
                                                        "Swift Flight Form",
                                                        "Ghost Wolf",
                                                        "Lichborne",
                                                    }) &&
                                    !DebuffDot(unit) &&
                                    !InvulnerableSpell(unit) &&
                                    (!IsTargetedByOurUnit(unit) ||
                                     unit.Mounted && IsMoving(unit)) &&
                                    Attackable(unit, 30));
                }
            }

            return BasicCheck(UnitRepentance);
        }

        private static Composite RepentanceComp()
        {
            return new PrioritySelector(
                new Decorator(
                    ret =>
                    THSettings.Instance.RepentanceCC &&
                    //SSpellManager.HasSpell("Repentance") &&
                    HealWeightMe > THSettings.Instance.PriorityHeal &&
                    (InArena || InBattleground) &&
                    !IsMoving(Me) &&
                    GetUnitRepentance() && UnitRepentance.IsValid &&
                    CanCastCheck("Repentance"),
                    new Action(delegate
                        {
                            CastSpell("Repentance", UnitRepentance);
                            Blacklist.Add(UnitRepentance.Guid, BlacklistFlags.All, TimeSpan.FromSeconds(1));
                        }))
                );
        }

        #endregion

        #region AutoRez

        private static readonly Dictionary<ulong, DateTime> AutoRezListCache = new Dictionary<ulong, DateTime>();

        private static void AutoRezListCacheClear()
        {
            var indexToRemove = AutoRezListCache.Where(
                unit =>
                unit.Value < DateTime.Now).Select(unit => unit.Key).ToList();

            foreach (var index in indexToRemove)
            {
                //Logging.Write("Remove {0} from AutoRezList", AutoRezList[index]);
                AutoRezListCache.Remove(index);
            }
        }

        private static void AutoRezListCacheAdd(WoWUnit unit, int expireSeconds = 20)
        {
            if (AutoRezListCache.ContainsKey(unit.Guid)) return;
            AutoRezListCache.Add(unit.Guid, DateTime.Now + TimeSpan.FromSeconds(expireSeconds));
        }

        private static WoWPlayer UnitAutoRez;

        private static bool GetUnitAutoRez()
        {
            AutoRezListCacheClear();
            UnitAutoRez = null;
            UnitAutoRez =
                ObjectManager.GetObjectsOfType<WoWPlayer>(false, false)
                             .FirstOrDefault(
                                 p =>
                                 !AutoRezListCache.ContainsKey(p.Guid) &&
                                 p.IsPlayer &&
                                 !p.IsAlive &&
                                 p.Distance < 100 &&
                                 p.IsInMyPartyOrRaid);

            return UnitAutoRez != null && UnitAutoRez.IsValid;
        }

        private static Composite AutoRez()
        {
            {
                return new Decorator(
                    ret =>
                    THSettings.Instance.AutoRez &&
                    //(InDungeon || InRaid) &&
                    !Me.Combat &&
                    //SSpellManager.HasSpell("Redemption") &&
                    GetUnitAutoRez() &&
                    CanCastCheck("Redemption"),
                    new PrioritySelector(
                        new Action(delegate
                            {
                                if (UnitAutoRez.Distance > 40 || !InLineOfSpellSightCheck(UnitAutoRez))
                                {
                                    Navigator.MoveTo(UnitAutoRez.Location);
                                }
                                else
                                {
                                    if (IsMoving(Me))
                                    {
                                        Navigator.PlayerMover.MoveStop();
                                    }
                                    CastSpell("Redemption", UnitAutoRez, "Redemption");
                                    AutoRezListCacheAdd(UnitAutoRez);
                                }
                            })
                        ))
                    ;
            }
        }

        #endregion

        #region Righteous Fury

        private static Composite RighteousFury()
        {
            return new PrioritySelector(
                new Decorator(
                    ret =>
                    THSettings.Instance.AutoRighteousFury &&
                    //SSpellManager.HasSpell("Righteous Fury") &&
                    !MeHasAura("Righteous Fury") &&
                    (//SSpellManager.HasSpell("Avenger's Shield") &&
                     (InDungeon ||
                      InRaid) ||
                     InArena ||
                     InBattleground) &&
                    CanCastCheck("Righteous Fury"),
                    new Action(delegate { CastSpell("Righteous Fury", Me); })),
                new Decorator(
                    ret =>
                    THSettings.Instance.AutoRighteousFury &&
                    MeHasAura("Righteous Fury") &&
                    !//SSpellManager.HasSpell("Avenger's Shield") &&
                    !InArena &&
                    !InBattleground,
                    new Action(delegate
                        {
                            CancelAura(25780, Me);
                            //Lua.DoString("RunMacroText('/cancelaura " + WoWSpell.FromId(25780) + "');");
                            return RunStatus.Failure;
                        }))
                );
        }

        #endregion

        #region SacredShieldHoly

        #region UnitHasSacredShield

        private static WoWUnit UnitHasSacredShield;
        //private static double UnitSacredShieldTotalDebuff;
        //private static double UnitSacredShieldTotalTargetted;

        private static bool GetUnitHasSacredShield()
        {
            UnitHasSacredShield = null;
            if (//SSpellManager.HasSpell("Sacred Shield"))
            {
                return false;
            }

            UnitHasSacredShield = FarFriendlyUnits.FirstOrDefault(unit => MyAura(20925, unit));

            return BasicCheck(UnitHasSacredShield);
        }

        #endregion

        private static WoWUnit UnitToSacredShield;

        private static bool GetUnitToSacredShield()
        {
            UnitToSacredShield = null;

            //Sacred Shield Tank PvE
            if (InRaid || InDungeon)
            {
                UnitToSacredShield = NearbyFriendlyPlayers.OrderBy(HealWeight).FirstOrDefault(
                    unit => BasicCheck(unit) &&
                            unit.HasAura("Vengeance") &&
                            IsEnemy(unit.CurrentTarget) &&
                            Healable(unit));
            }

            //Sacred Shield PvP
            //First Find Unit That Have Sacred Shield
            if (UnitToSacredShield == null)
            {
                GetUnitHasSacredShield();
            }

            //Sacred Shield UnitHeal if His HP lower than _unitHasSacredShield + 5%
            if (UnitToSacredShield == null &&
                BasicCheck(UnitHeal) &&
                (UnitHasSacredShield == null ||
                 UnitHasSacredShield != null &&
                 UnitHasSacredShield.IsValid &&
                 HealWeight(UnitHasSacredShield) > HealWeightUnitHeal) &&
                Healable(UnitHeal))
            {
                UnitToSacredShield = UnitHeal;
            }

            //Sacred Shield FC if his HP +5% lower than UnitHeal 
            if (UnitToSacredShield == null)
            {
                UnitToSacredShield = NearbyFriendlyPlayers.OrderByDescending(HealWeight).FirstOrDefault(
                    unit => BasicCheck(unit) &&
                            HasOneAura(unit,
                                       new HashSet<string>
                                           {
                                               "Alliance Flag",
                                               "Horde Flag",
                                               "Netherstorm Flag",
                                               "Orb of Power",
                                           }) &&
                            HealWeight(unit) < HealWeightUnitHeal + 10 &&
                            Healable(unit));
            }

            //Sacred Shield Most Focus Unit 
            if (UnitToSacredShield == null)
            {
                UnitToSacredShield = NearbyFriendlyPlayers.OrderByDescending(HealWeight).FirstOrDefault(
                    unit => BasicCheck(unit) &&
                            !MyAura("Sacred Shield", unit) &&
                            HealWeight(UnitHasSacredShield) < HealWeight(unit));
            }

            return BasicCheck(UnitToSacredShield);
        }

        //private static DateTime LastSacredShield;

        private static Composite SacredShieldHoly()
        {
            return new Decorator(
                ret =>
                //_lastCastSpell != "Sacred Shield" &&
                //LastSacredShield + TimeSpan.FromSeconds(15) < DateTime.Now &&
                //SSpellManager.HasSpell("Sacred Shield") &&
                ////!Me.Mounted &&
                !HasAuraPreparation &&
                !HasAuraArenaPreparation &&
                (Me.Combat || Me.IsInInstance) &&
                GetUnitToSacredShield() &&
                BasicCheck(UnitToSacredShield) &&
                !MyAura(20925, UnitToSacredShield) &&
                CanCastCheck("Sacred Shield"),
                new Action(delegate
                    {
                        //Logging.Write(LogLevel.Diagnostic, "Call UnitToSacredShield pls");
                        CastSpell("Sacred Shield", UnitToSacredShield);
                    })
                );
        }

        #endregion

        #region SacredShieldFriendRet

        private static Composite SacredShieldFriendRet()
        {
            return new Decorator(
                ret =>
                THSettings.Instance.SacredShieldRet &&
                //SSpellManager.HasSpell("Sacred Shield") &&
                ////!Me.Mounted &&
                !HasAuraPreparation &&
                !HasAuraArenaPreparation &&
                HealWeightMe > THSettings.Instance.PriorityHeal &&
                BasicCheck(UnitHeal) &&
                HealWeightUnitHeal < HealWeightMe - 20 &&
                !MyAura(20925, UnitHeal) &&
                CanCastCheck("Sacred Shield"),
                new Action(delegate { CastSpell("Sacred Shield", UnitHeal); })
                );
        }

        #endregion

        #region SacredShieldMeProt

        private static Composite SacredShieldMeProt()
        {
            return new Decorator(
                ret =>
                THSettings.Instance.SacredShieldProtMe &&
                //SSpellManager.HasSpell("Sacred Shield") &&
                ////!Me.Mounted &&
                !HasOneAura(Me,
                            new HashSet<string>
                                {
                                    "Preparation",
                                    "Arena Preparation",
                                    "Hand of Protection",
                                    "Divine Shield",
                                }) &&
                (Me.Combat ||
                 InDungeon ||
                 InRaid) &&
                MyAuraTimeLeft("Sacred Shield", Me) < 2000 &&
                CanCastCheck("Sacred Shield"),
                new Action(delegate { CastSpell("Sacred Shield", Me); })
                );
        }

        #endregion

        #region SacredShieldMeRet

        private static Composite SacredShieldMeRet()
        {
            return new Decorator(
                ret =>
                THSettings.Instance.SacredShieldRetMe &&
                //SSpellManager.HasSpell("Sacred Shield") &&
                ////!Me.Mounted &&
                !HasOneAura(Me, new HashSet<string>
                    {
                        "Preparation",
                        "Arena Preparation",
                        "Hand of Protection",
                        "Divine Shield",
                    }) &&
                (Me.Combat &&
                 HealWeightMe < THSettings.Instance.PriorityHeal ||
                 InArena &&
                 !GetUnitHaveMySacredShield() ||
                 InBattleground &&
                 !GetUnitHaveMySacredShield()) &&
                (!MeHasAura("Sacred Shield") ||
                 MyAuraTimeLeft("Sacred Shield", Me) < 2000) &&
                CanCastCheck("Sacred Shield"),
                new Action(delegate { CastSpell("Sacred Shield", Me); })
                );
        }

        #endregion

        #region SacredShieldProt

        private static WoWUnit UnitSacredShieldProt;

        private static bool GetUnitSacredShieldProt()
        {
            UnitSacredShieldProt = null;
            UnitSacredShieldProt = NearbyFriendlyUnits.OrderBy(unit => CountEnemyTargettingUnit(unit, 40))
                                                      .FirstOrDefault(
                                                          unit => BasicCheck(unit) &&
                                                                  unit.Combat &&
                                                                  unit.HasAura("Vengeance") &&
                                                                  !MyAura(20925, unit) &&
                                                                  CountEnemyTargettingUnit(unit, 40) > 0 &&
                                                                  Healable(unit));

            return BasicCheck(UnitSacredShieldProt);
        }

        private static Composite SacredShieldTankProt()
        {
            return new Decorator(
                ret =>
                THSettings.Instance.SacredShieldProt &&
                //SSpellManager.HasSpell("Sacred Shield") &&
                ////!Me.Mounted &&
                !HasAuraPreparation &&
                !HasAuraArenaPreparation &&
                CountEnemyTargettingUnit(Me, 40) <= 0 &&
                GetUnitSacredShieldProt() &&
                CanCastCheck("Sacred Shield"),
                new Action(delegate { CastSpell("Sacred Shield", UnitSacredShieldProt, "SacredShieldProt"); })
                );
        }

        #endregion

        #region Survive Rotation

        private static Composite CrowdControlHPSurviveComp()
        {
            return new PrioritySelector(
                new Decorator(
                    ret =>
                    THSettings.Instance.HammerofJusticeLow &&
                    //SSpellManager.HasSpell("Fist of Justice") &&
                    ////!Me.Mounted &&
                    GetUnitCroudControlSurvive(20, THSettings.Instance.HammerofJusticeLowHP) &&
                    !InvulnerableStun(UnitCroudControlSurvive) &&
                    CanCastCheck("Fist of Justice"),
                    new Action(
                        delegate { CastSpell("Fist of Justice", UnitCroudControlSurvive, "Fist of Justice Survive"); })
                    ),
                new Decorator(
                    ret =>
                    THSettings.Instance.HammerofJusticeLow &&
                    //SSpellManager.HasSpell("Hammer of Justice") &&
                    ////!Me.Mounted &&
                    GetUnitCroudControlSurvive(10, THSettings.Instance.HammerofJusticeLowHP) &&
                    !InvulnerableStun(UnitCroudControlSurvive) &&
                    CanCastCheck("Hammer of Justice"),
                    new Action(
                        delegate
                            { CastSpell("Hammer of Justice", UnitCroudControlSurvive, "Hammer of Justice Survive"); })
                    ),
                new Decorator(
                    ret =>
                    ////!Me.Mounted &&
                    THSettings.Instance.BlindingLightLow &&
                    //SSpellManager.HasSpell("Blinding Light") &&
                    (!IsMoving(Me) ||
                     IsMoving(Me) &&
                     Me.Specialization != WoWSpec.PaladinHoly) &&
                    GetUnitCroudControlSurvive(10, THSettings.Instance.BlindingLightLowHP) &&
                    CanCastCheck("Blinding Light"),
                    new Action(delegate
                        {
                            CastSpell("Blinding Light", UnitCroudControlSurvive, "BlindingLightLow");
                            Lua.DoString("RunMacroText('/stopattack');");
                        })
                    )
                );
        }

        #endregion

        #region SealofInsight

        private static Composite SealofInsight()
        {
            return new Decorator(
                ret =>
                //SSpellManager.HasSpell("Seal of Insight") &&
                SealSwitchLast < DateTime.Now &&
                ////!Me.Mounted &&
                !MeHasAura("Seal of Insight") &&
                !MeHasAura("Seal of Truth") &&
                CanCastCheck("Seal of Insight"),
                new Action(delegate
                    {
                        SealSwitchLast = DateTime.Now + TimeSpan.FromSeconds(10);
                        CastSpell("Seal of Insight", Me);
                    })
                );
        }

        #endregion

        #region SealofRighteousness

        private static DateTime SealSwitchLast;

        private static Composite SealofRighteousness()
        {
            return new Decorator(
                ret =>
                THSettings.Instance.SealofRighteousnessRet &&
                SealSwitchLast < DateTime.Now &&
                //SSpellManager.HasSpell("Seal of Righteousness") &&
                ////!Me.Mounted &&
                !InBattleground &&
                !InArena &&
                !MeHasAura("Seal of Righteousness") &&
                CountEnemyNeary(Me, 8) >= THSettings.Instance.SealofRighteousnessRetNumber &&
                CanCastCheck("Seal of Righteousness"),
                new Action(delegate
                    {
                        SealSwitchLast = DateTime.Now + TimeSpan.FromSeconds(10);
                        CastSpell("Seal of Righteousness", Me);
                    })
                );
        }

        #endregion

        #region Shield of the Righteous

        private static Composite ShieldoftheRighteous()
        {
            return new Decorator(
                ret =>
                THSettings.Instance.ShieldofRighterous &&
                //SSpellManager.HasSpell("Shield of the Righteous") &&
                Me.Inventory.Equipped.OffHand != null &&
                HealWeightMe > THSettings.Instance.WordofGloryMeRetHP &&
                ////!Me.Mounted &&
                !MeHasAura("Hand of Protection") &&
                CurrentTargetAttackable(5) &&
                FacingOverride(Me.CurrentTarget) &&
                (PlayerHolyPower >= THSettings.Instance.ShieldofRighterousHP ||
                 MeHasAura(90174)) &&
                CanCastCheck("Shield of the Righteous", true),
                new Action(delegate
                    {
                        SafelyFacingTarget(Me.CurrentTarget);
                        CastSpell("Shield of the Righteous", Me.CurrentTarget);
                        return RunStatus.Failure;
                    })
                );
        }

        #endregion

        #region SealofTruth

        private static Composite SealofTruth()
        {
            return new PrioritySelector(
                new Decorator(
                    ret =>
                    SealSwitchLast < DateTime.Now &&
                    //SSpellManager.HasSpell("Seal of Truth") &&
                    ////!Me.Mounted &&
                    !HasOneAura(Me,
                                new HashSet<string>
                                    {
                                        "Seal of Truth",
                                        "Seal of Righteousness",
                                        "Seal of Justice",
                                        "Seal of Insight",
                                    }) &&
                    CanCastCheck("Seal of Truth"),
                    new Action(delegate
                        {
                            SealSwitchLast = DateTime.Now + TimeSpan.FromSeconds(10);
                            CastSpell("Seal of Truth", Me);
                        })
                    ),
                new Decorator(
                    ret =>
                    SealSwitchLast < DateTime.Now &&
                    !//SSpellManager.HasSpell("Seal of Truth") &&
                    //SSpellManager.HasSpell("Seal of Command") &&
                    ////!Me.Mounted &&
                    !MeHasAura("Seal of Command") &&
                    CanCastCheck("Seal of Command"),
                    new Action(delegate
                        {
                            SealSwitchLast = DateTime.Now + TimeSpan.FromSeconds(10);
                            CastSpell("Seal of Command", Me);
                        })
                    ));
        }

        #endregion

        #region SealofTruthfromRighteousness

        private static Composite SealofTruthfromRighteousness()
        {
            return new Decorator(
                ret =>
                THSettings.Instance.SealofRighteousnessRet &&
                SealSwitchLast < DateTime.Now &&
                //SSpellManager.HasSpell("Seal of Truth") &&
                ////!Me.Mounted &&
                !HasOneAura(Me,
                            new HashSet<string>
                                {
                                    "Seal of Truth",
                                    "Seal of Justice",
                                    "Seal of Insight",
                                }) &&
                CountEnemyNeary(Me, 8) <= THSettings.Instance.SealofRighteousnessRetNumber &&
                CanCastCheck("Seal of Truth"),
                new Action(delegate
                    {
                        SealSwitchLast = DateTime.Now + TimeSpan.FromSeconds(10);
                        CastSpell("Seal of Truth", Me, "SealofTruthfromRighteousness");
                    })
                );
        }

        #endregion

        #region SealProtection

        private static string ProtPreferedSeal;

        private static Composite SealProtection()
        {
            return new PrioritySelector(
                //new Decorator(
                //    ret =>
                //    ////!Me.Mounted &&
                //    !Casting(),
                //    new Action(delegate
                //        {
                //            if (MeHasAura("Seal of Truth"))
                //            {
                //                ProtPreferedSeal = "Seal of Truth";
                //            }
                //            else
                //            {
                //                ProtPreferedSeal = "Seal of Insight";
                //            }
                //            return RunStatus.Failure;
                //        })),
                new Decorator(
                    ret =>
                    //SSpellManager.HasSpell("Seal of Command") &&
                    SealSwitchLast < DateTime.Now &&
                    ////!Me.Mounted &&
                    !MeHasAura("Seal of Command") &&
                    CanCastCheck("Seal of Command"),
                    new Action(delegate
                        {
                            SealSwitchLast = DateTime.Now + TimeSpan.FromSeconds(10);
                            CastSpell("Seal of Command", Me);
                        })),
                new Decorator(
                    ret =>
                    //SSpellManager.HasSpell("Seal of Insight") &&
                    SealSwitchLast < DateTime.Now &&
                    ////!Me.Mounted &&
                    !HasOneAura(Me,
                                new HashSet<string>
                                    {
                                        "Seal of Truth",
                                        "Seal of Righteousness",
                                        "Seal of Insight",
                                    }) &&
                    //SSpellManager.HasSpell("Seal of Insight"),
                    new Action(delegate
                        {
                            SealSwitchLast = DateTime.Now + TimeSpan.FromSeconds(10);
                            CastSpell("Seal of Insight", Me);
                        })),
                new Decorator(
                    ret =>
                    THSettings.Instance.SealofRighteousnessProt &&
                    //SSpellManager.HasSpell("Seal of Righteousness") &&
                    SealSwitchLast < DateTime.Now &&
                    ////!Me.Mounted &&
                    Me.Combat &&
                    !MeHasAura("Seal of Righteousness") &&
                    CountEnemyNeary(Me, 8) >= THSettings.Instance.SealofRighteousnessProtNumber &&
                    CanCastCheck("Seal of Righteousness"),
                    new Action(delegate
                        {
                            if (MeHasAura("Seal of Truth"))
                            {
                                ProtPreferedSeal = "Seal of Truth";
                            }
                            else if (MeHasAura("Seal of Command"))
                            {
                                ProtPreferedSeal = "Seal of Command";
                            }
                            else if (MeHasAura("Seal of Insight"))
                            {
                                ProtPreferedSeal = "Seal of Insight";
                            }
                            SealSwitchLast = DateTime.Now + TimeSpan.FromSeconds(10);
                            CastSpell("Seal of Righteousness", Me, "SealofRighteousnessProt");
                        })),
                new Decorator(
                    ret =>
                    //SSpellManager.HasSpell(ProtPreferedSeal) &&
                    SealSwitchLast < DateTime.Now &&
                    ////!Me.Mounted &&
                    //Me.Combat &&
                    MeHasAura("Seal of Righteousness") &&
                    ProtPreferedSeal != null &&
                    CountEnemyNeary(Me, 8) <= THSettings.Instance.SealofRighteousnessRetNumber &&
                    CanCastCheck(ProtPreferedSeal),
                    new Action(delegate
                        {
                            SealSwitchLast = DateTime.Now + TimeSpan.FromSeconds(10);
                            CastSpell(ProtPreferedSeal, Me);
                        }))
                );
        }

        #endregion

        #region SpeedofLight

        private static Composite SpeedofLight()
        {
            return new Decorator(
                ret =>
                THSettings.Instance.SpeedofLight &&
                //SSpellManager.HasSpell("Speed of Light") &&
                IsMoving(Me) &&
                !DebuffRootorSnare(Me) &&
                CountEnemyNeary(Me, THSettings.Instance.SpeedofLightDistance) > 0 &&
                CanCastCheck("Speed of Light"),
                new Action(delegate { CastSpell("Speed of Light", Me, "SpeedofLight"); }));
        }

        #endregion

        #region StopCastingCheck

        private void StopCastingCheck()
        {
            //Stop Casting Healing Spells
            if (Me.IsCasting &&
                (Me.CastingSpell.Name == "Holy Light" && LastCastSpell == "Holy Light" ||
                 Me.CastingSpell.Name == "Flash of Light" && LastCastSpell == "Flash of Light" ||
                 Me.CastingSpell.Name == "Divine Light" && LastCastSpell == "Divine Light"))
            {
                if (LastCastUnit != null && (!LastCastUnit.IsValid || !LastCastUnit.IsAlive))
                {
                    SpellManager.StopCasting();
                    Blacklist.Add(LastCastUnit.Guid, BlacklistFlags.All, TimeSpan.FromSeconds(1));
                    Logging.Write(DateTime.Now.ToString("ss:fff ") + "Stop Casting: Unit is Dead");
                }
                else
                {
                    if (Me.IsCasting &&
                        BasicCheck(LastCastUnit) &&
                        Me.CastingSpell.Name == "Divine Light" &&
                        (HealWeight(LastCastUnit) >=
                         THSettings.Instance.DoNotHealAbove - THSettings.Instance.HealBalancing ||
                         HealWeight(LastCastUnit) >= THSettings.Instance.DivineLightHP + 25))
                    {
                        SpellManager.StopCasting();
                        Logging.Write(DateTime.Now.ToString("ss:fff ") + "Stop Casting: Save Mana Divine Light");
                    }

                    if (Me.IsCasting &&
                        BasicCheck(LastCastUnit) &&
                        Me.CastingSpell.Name == "Flash of Light" && //SSpellManager.HasSpell("Holy Light") &&
                        (HealWeight(LastCastUnit) >=
                         THSettings.Instance.DoNotHealAbove - THSettings.Instance.HealBalancing
                         || HealWeight(LastCastUnit) >= THSettings.Instance.FlashofLightHolyHP + 20))
                    {
                        SpellManager.StopCasting();
                        Logging.Write(DateTime.Now.ToString("ss:fff ") + "Stop Casting: Save Mana Flash of Light");
                    }

                    if (!InDungeon && !InRaid &&
                        Me.IsCasting &&
                        BasicCheck(LastCastUnit) &&
                        Me.CastingSpell.Name == "Holy Light" &&
                        Me.CurrentCastTimeLeft.TotalMilliseconds > 1300 &&
                        HealWeight(LastCastUnit) < THSettings.Instance.DivineLightHP &&
                        (LastCastUnit.Combat || Me.Combat))
                    {
                        SpellManager.StopCasting();
                        Logging.Write(DateTime.Now.ToString("ss:fff ") + "Stop Casting Holy Light. Need Faster Heal!");
                    }

                    if (Me.IsCasting &&
                        Me.CastingSpell.Name == "Divine Light" && Me.GetAuraById(54149) == null &&
                        (InBattleground || InArena))
                    {
                        SpellManager.StopCasting();
                        Logging.Write(DateTime.Now.ToString("ss:fff ") + "Stop Casting " + LastCastSpell +
                                      ": No Infusion of Light");
                    }

                    if (Me.IsCasting && Me.CastingSpell.Name != "Holy Light" && LastCastUnit != null &&
                        LastCastUnit.IsValid &&
                        HealWeight(LastCastUnit) >
                        THSettings.Instance.DoNotHealAbove - THSettings.Instance.HealBalancing)
                    {
                        SpellManager.StopCasting();
                        Blacklist.Add(LastCastUnit.Guid, BlacklistFlags.All, TimeSpan.FromSeconds(1));
                        Logging.Write(DateTime.Now.ToString("ss:fff ") + "Stop Casting: Unit Full HP");
                    }

                    if (Me.IsCasting && LastCastUnit != null && LastCastUnit.IsValid &&
                        !InLineOfSpellSightCheck(LastCastUnit))
                    {
                        SpellManager.StopCasting();
                        Blacklist.Add(LastCastUnit.Guid, BlacklistFlags.All, TimeSpan.FromSeconds(1));
                        Logging.Write(DateTime.Now.ToString("ss:fff ") + "Stop Casting: Unit not In Line of Spell Sight");
                    }

                    if (Me.IsCasting && LastCastUnit != null && LastCastUnit.IsValid &&
                        GetDistance(LastCastUnit) > 40)
                    {
                        SpellManager.StopCasting();
                        Blacklist.Add(LastCastUnit.Guid, BlacklistFlags.All, TimeSpan.FromSeconds(1));
                        Logging.Write(DateTime.Now.ToString("ss:fff ") + "Stop Casting: Unit out of range");
                    }
                }
            }

            //Stop Casting Denounce
            if (Me.IsCasting && Me.CastingSpell.Name == "Denounce" && LastCastSpell == "Denounce")
            {
                if (LastCastUnit != null && (!LastCastUnit.IsValid || !LastCastUnit.IsAlive))
                {
                    UnitAttack = null;
                    SpellManager.StopCasting();
                    Blacklist.Add(LastCastUnit.Guid, BlacklistFlags.All, TimeSpan.FromSeconds(1));
                    Logging.Write(DateTime.Now.ToString("ss:fff ") + "Stop Casting: Unit is Dead");
                }
                else
                {
                    if (Me.IsCasting && LastCastUnit != null && LastCastUnit.IsValid &&
                        !InLineOfSpellSightCheck(LastCastUnit))
                    {
                        UnitAttack = null;
                        SpellManager.StopCasting();
                        Blacklist.Add(LastCastUnit.Guid, BlacklistFlags.All, TimeSpan.FromSeconds(1));
                        Logging.Write(DateTime.Now.ToString("ss:fff ") + "Stop Casting: Unit not In Line of Spell Sight");
                    }
                    if (Me.IsCasting && LastCastUnit != null && LastCastUnit.IsValid &&
                        GetDistance(LastCastUnit) > 30)
                    {
                        UnitAttack = null;
                        SpellManager.StopCasting();
                        Blacklist.Add(LastCastUnit.Guid, BlacklistFlags.All, TimeSpan.FromSeconds(1));
                        Logging.Write(DateTime.Now.ToString("ss:fff ") + "Stop Casting: Unit out of range");
                    }

                    if (Me.IsCasting && LastCastUnit != null && LastCastUnit.IsValid &&
                        DebuffCCBreakonDamage(LastCastUnit))
                    {
                        UnitAttack = null;
                        SpellManager.StopCasting();
                        Blacklist.Add(LastCastUnit.Guid, BlacklistFlags.All, TimeSpan.FromSeconds(1));
                        Logging.Write(DateTime.Now.ToString("ss:fff ") +
                                      "Stop Casting: Unit Have Debuff Break on Damage");
                    }
                    if (UnitHeal != null && UnitHeal.IsValid &&
                        HealWeightUnitHeal < THSettings.Instance.PriorityHeal)
                    {
                        SpellManager.StopCasting();
                        Logging.Write(DateTime.Now.ToString("ss:fff ") + "Stop Casting Denounce: Need Heal First");
                    }
                }
            }

            //Stop Casting Repentance
            if (Me.IsCasting && Me.CastingSpell.Name == "Repentance" && LastCastSpell == "Repentance")
            {
                if (LastCastUnit != null && (!LastCastUnit.IsValid || !LastCastUnit.IsAlive))
                {
                    UnitAttack = null;
                    SpellManager.StopCasting();
                    Blacklist.Add(LastCastUnit.Guid, BlacklistFlags.All, TimeSpan.FromSeconds(1));
                    Logging.Write(DateTime.Now.ToString("ss:fff ") + "Stop Casting: Unit is Dead");
                }
                else
                {
                    if (Me.IsCasting && LastCastUnit != null && LastCastUnit.IsValid &&
                        !InLineOfSpellSightCheck(LastCastUnit))
                    {
                        UnitAttack = null;
                        SpellManager.StopCasting();
                        Blacklist.Add(LastCastUnit.Guid, BlacklistFlags.All, TimeSpan.FromSeconds(1));
                        Logging.Write(DateTime.Now.ToString("ss:fff ") + "Stop Casting: Unit not In Line of Spell Sight");
                    }
                    if (Me.IsCasting && LastCastUnit != null && LastCastUnit.IsValid &&
                        GetDistance(LastCastUnit) > 30)
                    {
                        UnitAttack = null;
                        SpellManager.StopCasting();
                        Blacklist.Add(LastCastUnit.Guid, BlacklistFlags.All, TimeSpan.FromSeconds(1));
                        Logging.Write(DateTime.Now.ToString("ss:fff ") + "Stop Casting: Unit out of range");
                    }

                    if (Me.IsCasting && LastCastUnit != null && LastCastUnit.IsValid && DebuffCC(LastCastUnit))
                    {
                        UnitAttack = null;
                        SpellManager.StopCasting();
                        Blacklist.Add(LastCastUnit.Guid, BlacklistFlags.All, TimeSpan.FromSeconds(1));
                        Logging.Write(DateTime.Now.ToString("ss:fff ") + "Stop Casting: Unit is Croud Controlled");
                    }
                    if (UnitHeal != null && UnitHeal.IsValid &&
                        HealWeightUnitHeal < THSettings.Instance.PriorityHeal)
                    {
                        SpellManager.StopCasting();
                        Logging.Write(DateTime.Now.ToString("ss:fff ") + "Stop Casting Denounce: Need Heal First");
                    }
                }
            }
        }

        #endregion

        #region TemplarsVerdict3HolyPower

        private static Composite TemplarsVerdict3HolyPower()
        {
            return new Decorator(
                ret =>
                THSettings.Instance.TemplarsVerdict &&
                //SSpellManager.HasSpell("Templar's Verdict") &&
                ////!Me.Mounted &&
                !MeHasAura("Hand of Protection") &&
                MyAuraTimeLeft(84963, Me) > 7000 &&
                CurrentTargetAttackable(5) &&
                FacingOverride(Me.CurrentTarget) &&
                (PlayerHolyPower >= 3 ||
                 MeHasAura(90174)) &&
                CanCastCheck("Templar's Verdict"),
                new Action(delegate
                    {
                        SafelyFacingTarget(Me.CurrentTarget);
                        CastSpell("Templar's Verdict", Me.CurrentTarget);
                    })
                );
        }

        #endregion

        #region TemplarsVerdict5HolyPower

        private static Composite TemplarsVerdict5HolyPower()
        {
            return new Decorator(
                ret =>
                THSettings.Instance.TemplarsVerdict &&
                //SSpellManager.HasSpell("Templar's Verdict") &&
                ////!Me.Mounted &&
                !MeHasAura("Hand of Protection") &&
                CurrentTargetAttackable(5) &&
                FacingOverride(Me.CurrentTarget) &&
                (PlayerHolyPower >= Me.MaxHolyPower ||
                 MeHasAura(90174) ||
                 PlayerHolyPower >= 3 &&
                 MeHasAura("Holy Avenger")) &&
                CanCastCheck("Templar's Verdict"),
                new Action(delegate
                    {
                        SafelyFacingTarget(Me.CurrentTarget);
                        CastSpell("Templar's Verdict", Me.CurrentTarget);
                    }));
        }

        #endregion

        #region TurnEvilComp

        private static WoWUnit UnitTurnEvilASAP;

        private static bool GetUnitTurnEvilASAP()
        {
            UnitTurnEvilASAP = null;

            UnitTurnEvilASAP = NearbyUnFriendlyUnits.FirstOrDefault(
                unit => BasicCheck(unit) &&
                        (unit.Entry == 59190 ||
                         unit.HasAura("Lichborne") ||
                         unit.HasAura("Dark Transformation") ||
                         unit.Entry == 27829 || //unit.Name == "Ebon Gargoyle" ||
                         unit.IsPet &&
                         unit.IsDemon &&
                         (unit.IsCasting ||
                          unit.IsChanneling)) &&
                        !InvulnerableSpell(unit) &&
                        !DebuffCC(unit) &&
                        Attackable(unit, 20));

            return BasicCheck(UnitTurnEvilASAP);
        }

        private static WoWUnit UnitTurnEvil;

        private static bool GetUnitTurnEvil()
        {
            UnitTurnEvil = null;

            UnitTurnEvil = NearbyUnFriendlyUnits.FirstOrDefault(
                unit => BasicCheck(unit) &&
                        (unit.IsDemon ||
                         unit.IsUndead) &&
                        !DebuffCC(unit) &&
                        Attackable(unit, 20));

            return BasicCheck(UnitTurnEvil);
        }

        private static Composite TurnEvilComp()
        {
            return new PrioritySelector(
                new Decorator(
                    ret =>
                    THSettings.Instance.TurnEvil &&
                    //SSpellManager.HasSpell("Turn Evil") &&
                    Me.Combat &&
                    HasGlyph.Contains("54931") &&
                    GetUnitTurnEvil() &&
                    UnitTurnEvil != null &&
                    UnitTurnEvil.IsValid &&
                    UnitTurnEvil.Distance < 20 &&
                    CanCastCheck("Turn Evil"),
                    new Action(delegate
                        {
                            //Logging.Write(LogLevel.Diagnostic, "Found UnitTurnEvil");
                            CastSpell("Turn Evil", UnitTurnEvil);
                            UnitTurnEvilASAP = null;
                        }))
                );
        }

        private static Composite TurnEvilASAPComp()
        {
            return new PrioritySelector(
                new Decorator(
                    ret =>
                    THSettings.Instance.TurnEvilASAP &&
                    //SSpellManager.HasSpell("Turn Evil") &&
                    Me.Combat &&
                    HasGlyph.Contains("54931") &&
                    GetUnitTurnEvilASAP() &&
                    UnitTurnEvilASAP != null &&
                    UnitTurnEvilASAP.IsValid &&
                    UnitTurnEvilASAP.Distance < 20 &&
                    CanCastCheck("Turn Evil"),
                    new Action(delegate
                        {
                            //Logging.Write(LogLevel.Diagnostic, "Found UnitTurnEvil");
                            CastSpell("Turn Evil", UnitTurnEvilASAP);
                            UnitTurnEvilASAP = null;
                        }))
                );
        }

        #endregion

        #region UseRacial

        private static Composite UseRacial()
        {
            return new PrioritySelector(
                new Decorator(
                    ret =>
                    THSettings.Instance.AutoRacial &&
                    //SSpellManager.HasSpell("Every Man for Himself") &&
                    Me.Combat &&
                    !MeHasAura("Sap") &&
                    !MeHasAura("Scatter Shot") &&
                    CanCastCheck("Every Man for Himself", true) &&
                    DebuffCCDuration(Me, 3000),
                    new Action(delegate
                        {
                            if (THSettings.Instance.AutoTarget && Me.CurrentTarget == null &&
                                MyLastTarget != null &&
                                MyLastTarget.IsValid)
                            {
                                MyLastTarget.Target();
                            }

                            Logging.Write("Use: Every Man for Himself");
                            CastSpell("Every Man for Himself", Me);
                            return RunStatus.Failure;
                        })),
                //Stoneform
                new Decorator(
                    ret =>
                    THSettings.Instance.AutoRacial && HealWeightMe < THSettings.Instance.UrgentHeal &&
                    //SSpellManager.HasSpell("Stoneform") &&
                    Me.Combat &&
                    CanCastCheck("Stoneform", true),
                    new Action(delegate
                        {
                            {
                                //Logging.Write("Stoneform");
                                CastSpell("Stoneform", Me);
                            }
                            return RunStatus.Failure;
                        })),
                new Decorator(
                    ret =>
                    THSettings.Instance.AutoRacial &&
                    HealWeightMe < THSettings.Instance.UrgentHeal &&
                    //SSpellManager.HasSpell("Gift of the Naaru") &&
                    Me.Combat &&
                    CanCastCheck("Gift of the Naaru", true),
                    new Action(delegate
                        {
                            {
                                //Logging.Write("Gift of the Naaru");
                                CastSpell("Gift of the Naaru", Me);
                            }
                            return RunStatus.Failure;
                        })) //,
                //new Decorator(
                //    ret =>
                //    THSettings.Instance.AutoRacial && Me.ManaPercent < THSettings.Instance.PriorityHeal &&
                //    //SSpellManager.HasSpell("Arcane Torrent") && //SSpellManager.HasSpell("Holy Insight") &&
                //    Me.Combat &&
                //    (InDungeon || InRaid) &&
                //    CanCastCheck("Arcane Torrent", true),
                //    new Action(delegate
                //        {
                //            {
                //                Logging.Write("Arcane Torrent");
                //                CastSpell("Arcane Torrent", Me);
                //            }
                //            return RunStatus.Failure;
                //        }))
                );
        }

        #endregion

        #region UseTrinket

        private static DateTime LastBreakCC;

        private static Composite UseTrinket()
        {
            return new PrioritySelector(
                new Decorator(
                    ret =>
                    THSettings.Instance.Trinket1 == 1 &&
                    //LastCastSpell != "STrinket1" &&
                    Me.Combat &&
                    Me.Inventory.Equipped.Trinket1 != null &&
                    CanUseCheck(Me.Inventory.Equipped.Trinket1),
                    new Action(delegate
                        {
                            Logging.Write("Activate " + StyxWoW.Me.Inventory.Equipped.Trinket1.Name +
                                          " on Cooldown");
                            StyxWoW.Me.Inventory.Equipped.Trinket1.Use();
                            LastCastSpell = "STrinket1";
                            return RunStatus.Failure;
                        })),
                new Decorator(
                    ret =>
                    THSettings.Instance.Trinket1 == 2 &&
                    //LastCastSpell != "STrinket1" &&
                    Me.Combat &&
                    CurrentTargetAttackable(30) &&
                    Me.CurrentTarget.IsBoss &&
                    Me.Inventory.Equipped.Trinket1 != null &&
                    CanUseCheck(Me.Inventory.Equipped.Trinket1),
                    new Action(delegate
                        {
                            Logging.Write("Activate " + StyxWoW.Me.Inventory.Equipped.Trinket1.Name +
                                          " on Cooldown (Boss Only");
                            StyxWoW.Me.Inventory.Equipped.Trinket1.Use();
                            LastCastSpell = "STrinket1";
                            return RunStatus.Failure;
                        })),
                new Decorator(
                    ret =>
                    THSettings.Instance.Trinket1 == 3 &&
                    //LastCastSpell != "STrinket1" &&
                    THSettings.Instance.Burst &&
                    Me.Combat &&
                    Me.Inventory.Equipped.Trinket1 != null &&
                    CanUseCheck(Me.Inventory.Equipped.Trinket1),
                    new Action(delegate
                        {
                            Logging.Write("Activate " + StyxWoW.Me.Inventory.Equipped.Trinket1.Name +
                                          " on Burst Mode");
                            StyxWoW.Me.Inventory.Equipped.Trinket1.Use();
                            LastCastSpell = "STrinket1";
                            return RunStatus.Failure;
                        })),
                new Decorator(
                    ret =>
                    THSettings.Instance.Trinket1 == 4 &&
                    LastBreakCC < DateTime.Now &&
                    Me.Combat &&
                    Me.Inventory.Equipped.Trinket1 != null &&
                    !MeHasAura("Scatter Shot") &&
                    //!MeHasAura("Cheap Shot") &&
                    !MeHasAura("Sap") &&
                    DebuffCCDuration(Me, 3000, true) &&
                    CanUseCheck(Me.Inventory.Equipped.Trinket1),
                    new Action(delegate
                        {
                            //if (CanCastCheck("Tremor Totem") && NeedTremor(Me, 3000))
                            //{
                            //    CastSpell("Tremor Totem", Me, "Tremor Totem instead of Trinket");
                            //}
                            //else
                            //{
                            StyxWoW.Me.Inventory.Equipped.Trinket1.Use();
                            Logging.Write("Activate " + StyxWoW.Me.Inventory.Equipped.Trinket1.Name +
                                          " on Lose Control");
                            LastCastSpell = "STrinket1";
                            //}
                            LastBreakCC = DateTime.Now + TimeSpan.FromMilliseconds(1500);
                            return RunStatus.Failure;
                        })),
                new Decorator(
                    ret =>
                    THSettings.Instance.Trinket1 == 5 &&
                    //LastCastSpell != "STrinket1" &&
                    Me.Combat &&
                    Me.Inventory.Equipped.Trinket1 != null &&
                    HealWeightMe < THSettings.Instance.Trinket1HP &&
                    CanUseCheck(Me.Inventory.Equipped.Trinket1),
                    new Action(delegate
                        {
                            Logging.Write("Activate " + StyxWoW.Me.Inventory.Equipped.Trinket1.Name +
                                          " on Low HP");
                            StyxWoW.Me.Inventory.Equipped.Trinket1.Use();
                            LastCastSpell = "STrinket1";
                            return RunStatus.Failure;
                        })),
                new Decorator(
                    ret =>
                    THSettings.Instance.Trinket1 == 6 &&
                    UnitHealIsValid &&
                    HealWeightUnitHeal <= THSettings.Instance.Trinket1HP &&
                    //LastCastSpell != "STrinket1" &&
                    Me.Combat &&
                    Me.Inventory.Equipped.Trinket1 != null &&
                    CanUseCheck(Me.Inventory.Equipped.Trinket1),
                    new Action(delegate
                        {
                            Logging.Write("Activate " + StyxWoW.Me.Inventory.Equipped.Trinket1.Name +
                                          " on Friendly Unit Low HP");
                            StyxWoW.Me.Inventory.Equipped.Trinket1.Use();
                            LastCastSpell = "STrinket1";
                            return RunStatus.Failure;
                        })),
                new Decorator(
                    ret =>
                    THSettings.Instance.Trinket1 == 7 &&
                    //LastCastSpell != "STrinket1" &&
                    Me.Combat &&
                    Me.Inventory.Equipped.Trinket1 != null &&
                    CurrentTargetAttackable(20) &&
                    !Me.CurrentTarget.IsPet &&
                    Me.CurrentTarget.HealthPercent <= THSettings.Instance.Trinket1HP &&
                    CanUseCheck(Me.Inventory.Equipped.Trinket1),
                    new Action(delegate
                        {
                            Logging.Write("Activate " + StyxWoW.Me.Inventory.Equipped.Trinket1.Name +
                                          " on Enemy Unit Low HP");
                            StyxWoW.Me.Inventory.Equipped.Trinket1.Use();
                            LastCastSpell = "STrinket1";
                            return RunStatus.Failure;
                        })),
                new Decorator(
                    ret =>
                    THSettings.Instance.Trinket1 == 8 &&
                    //LastCastSpell != "STrinket1" &&
                    Me.Combat &&
                    Me.Inventory.Equipped.Trinket1 != null &&
                    Me.ManaPercent <= THSettings.Instance.Trinket1HP &&
                    CanUseCheck(Me.Inventory.Equipped.Trinket1),
                    new Action(delegate
                        {
                            Logging.Write("Activate " + StyxWoW.Me.Inventory.Equipped.Trinket1.Name +
                                          " on Low Mana");
                            StyxWoW.Me.Inventory.Equipped.Trinket1.Use();
                            LastCastSpell = "STrinket1";
                            return RunStatus.Failure;
                        })),
                new Decorator(
                    ret =>
                    THSettings.Instance.Trinket1 == 9 &&
                    //LastCastSpell != "STrinket1" &&
                    Me.Combat &&
                    Me.Inventory.Equipped.Trinket1 != null &&
                    BuffBurst(Me) &&
                    CanUseCheck(Me.Inventory.Equipped.Trinket1),
                    new Action(delegate
                        {
                            Logging.Write("Activate " + StyxWoW.Me.Inventory.Equipped.Trinket1.Name +
                                          " on Using Cooldown");
                            StyxWoW.Me.Inventory.Equipped.Trinket1.Use();
                            LastCastSpell = "STrinket1";
                            return RunStatus.Failure;
                        })),
                //Trinket 2
                new Decorator(
                    ret =>
                    THSettings.Instance.Trinket2 == 1 &&
                    //LastCastSpell != "STrinket2" &&
                    Me.Combat &&
                    Me.Inventory.Equipped.Trinket2 != null &&
                    CanUseCheck(Me.Inventory.Equipped.Trinket2),
                    new Action(delegate
                        {
                            Logging.Write("Activate " + StyxWoW.Me.Inventory.Equipped.Trinket2.Name +
                                          " on Cooldown");
                            StyxWoW.Me.Inventory.Equipped.Trinket2.Use();
                            LastCastSpell = "STrinket2";
                            return RunStatus.Failure;
                        })),
                new Decorator(
                    ret =>
                    THSettings.Instance.Trinket2 == 2 &&
                    //LastCastSpell != "STrinket2" &&
                    Me.Combat &&
                    CurrentTargetAttackable(30) &&
                    Me.CurrentTarget.IsBoss &&
                    Me.Inventory.Equipped.Trinket2 != null &&
                    CanUseCheck(Me.Inventory.Equipped.Trinket2),
                    new Action(delegate
                        {
                            Logging.Write("Activate " + StyxWoW.Me.Inventory.Equipped.Trinket2.Name +
                                          " on Cooldown (Boss Only");
                            StyxWoW.Me.Inventory.Equipped.Trinket2.Use();
                            LastCastSpell = "STrinket2";
                            return RunStatus.Failure;
                        })),
                new Decorator(
                    ret =>
                    THSettings.Instance.Trinket2 == 3 &&
                    //LastCastSpell != "STrinket2" &&
                    THSettings.Instance.Burst &&
                    Me.Combat &&
                    Me.Inventory.Equipped.Trinket2 != null &&
                    CanUseCheck(Me.Inventory.Equipped.Trinket2),
                    new Action(delegate
                        {
                            Logging.Write("Activate " + StyxWoW.Me.Inventory.Equipped.Trinket2.Name +
                                          " on Burst Mode");
                            StyxWoW.Me.Inventory.Equipped.Trinket2.Use();
                            LastCastSpell = "STrinket2";
                            return RunStatus.Failure;
                        })),
                new Decorator(
                    ret =>
                    THSettings.Instance.Trinket2 == 4 &&
                    //LastCastSpell != "STrinket2" &&
                    LastBreakCC < DateTime.Now &&
                    Me.Combat &&
                    Me.Inventory.Equipped.Trinket2 != null &&
                    !MeHasAura("Scatter Shot") &&
                    !MeHasAura("Sap") &&
                    DebuffCCDuration(Me, 3000, true) &&
                    CanUseCheck(Me.Inventory.Equipped.Trinket2),
                    new Action(delegate
                        {
                            //if (CanCastCheck("Tremor Totem") && NeedTremor(Me, 3000))
                            //{
                            //    CastSpell("Tremor Totem", Me, "Tremor Totem instead of Trinket");
                            //}
                            //else
                            //{
                            StyxWoW.Me.Inventory.Equipped.Trinket2.Use();
                            Logging.Write("Activate " + StyxWoW.Me.Inventory.Equipped.Trinket2.Name +
                                          " on Lose Control");
                            LastCastSpell = "STrinket2";
                            //}
                            LastBreakCC = DateTime.Now + TimeSpan.FromMilliseconds(1500);
                            return RunStatus.Failure;
                        })),
                new Decorator(
                    ret =>
                    THSettings.Instance.Trinket2 == 5 &&
                    //LastCastSpell != "STrinket2" &&.0.
                    Me.Combat &&
                    Me.Inventory.Equipped.Trinket2 != null &&
                    HealWeightMe <= THSettings.Instance.Trinket2HP &&
                    CanUseCheck(Me.Inventory.Equipped.Trinket2),
                    new Action(delegate
                        {
                            Logging.Write("Activate " + StyxWoW.Me.Inventory.Equipped.Trinket2.Name +
                                          " on Low HP");
                            StyxWoW.Me.Inventory.Equipped.Trinket2.Use();
                            LastCastSpell = "STrinket2";
                            return RunStatus.Failure;
                        })),
                new Decorator(
                    ret =>
                    THSettings.Instance.Trinket2 == 6 &&
                    UnitHealIsValid &&
                    HealWeightUnitHeal <= THSettings.Instance.Trinket2HP &&
                    //LastCastSpell != "STrinket2" &&
                    Me.Combat &&
                    Me.Inventory.Equipped.Trinket2 != null &&
                    CanUseCheck(Me.Inventory.Equipped.Trinket2),
                    new Action(delegate
                        {
                            Logging.Write("Activate " + StyxWoW.Me.Inventory.Equipped.Trinket2.Name +
                                          " on Friendly Unit Low HP");
                            StyxWoW.Me.Inventory.Equipped.Trinket2.Use();
                            LastCastSpell = "STrinket2";
                            return RunStatus.Failure;
                        })),
                new Decorator(
                    ret =>
                    THSettings.Instance.Trinket2 == 7 &&
                    //LastCastSpell != "STrinket2" &&
                    Me.Combat &&
                    Me.Inventory.Equipped.Trinket2 != null &&
                    CurrentTargetAttackable(20) &&
                    !Me.CurrentTarget.IsPet &&
                    Me.CurrentTarget.HealthPercent <= THSettings.Instance.Trinket2HP &&
                    CanUseCheck(Me.Inventory.Equipped.Trinket2),
                    new Action(delegate
                        {
                            Logging.Write("Activate " + StyxWoW.Me.Inventory.Equipped.Trinket2.Name +
                                          " on Enemy Unit Low HP");
                            StyxWoW.Me.Inventory.Equipped.Trinket2.Use();
                            LastCastSpell = "STrinket2";
                            return RunStatus.Failure;
                        })),
                new Decorator(
                    ret =>
                    THSettings.Instance.Trinket2 == 8 &&
                    //LastCastSpell != "STrinket2" &&
                    Me.Combat &&
                    Me.Inventory.Equipped.Trinket2 != null &&
                    Me.ManaPercent <= THSettings.Instance.Trinket2HP &&
                    CanUseCheck(Me.Inventory.Equipped.Trinket2),
                    new Action(delegate
                        {
                            Logging.Write("Activate " + StyxWoW.Me.Inventory.Equipped.Trinket2.Name +
                                          " on Low Mana");
                            StyxWoW.Me.Inventory.Equipped.Trinket2.Use();
                            LastCastSpell = "STrinket2";
                            return RunStatus.Failure;
                        })),
                new Decorator(
                    ret =>
                    THSettings.Instance.Trinket2 == 9 &&
                    //LastCastSpell != "STrinket2" &&
                    Me.Combat &&
                    Me.Inventory.Equipped.Trinket2 != null &&
                    BuffBurst(Me) &&
                    CanUseCheck(Me.Inventory.Equipped.Trinket2),
                    new Action(delegate
                        {
                            Logging.Write("Activate " + StyxWoW.Me.Inventory.Equipped.Trinket2.Name +
                                          " on Using Cooldown");
                            StyxWoW.Me.Inventory.Equipped.Trinket2.Use();
                            LastCastSpell = "STrinket2";
                            return RunStatus.Failure;
                        }))
                )
                ;
        }

        private static void UseTrinketVoid()
        {
            if (!Me.Combat || Me.Mounted)
            {
                return;
            }

            switch (THSettings.Instance.Trinket1)
            {
                case 1:
                    if (Me.Inventory.Equipped.Trinket1 != null &&
                        CanUseCheck(Me.Inventory.Equipped.Trinket1))
                    {
                        StyxWoW.Me.Inventory.Equipped.Trinket1.Use();
                        Logging.Write("Activate " + StyxWoW.Me.Inventory.Equipped.Trinket1.Name +
                                      " on Cooldown");
                    }
                    break;
                case 2:
                    if (CurrentTargetAttackable(30) &&
                        Me.CurrentTarget.IsBoss &&
                        Me.Inventory.Equipped.Trinket1 != null &&
                        CanUseCheck(Me.Inventory.Equipped.Trinket1))
                    {
                        StyxWoW.Me.Inventory.Equipped.Trinket1.Use();
                        Logging.Write("Activate " + StyxWoW.Me.Inventory.Equipped.Trinket1.Name +
                                      " on Cooldown (Boss Only");
                    }
                    break;
                case 3:
                    if (THSettings.Instance.Burst &&
                        Me.Inventory.Equipped.Trinket1 != null &&
                        CanUseCheck(Me.Inventory.Equipped.Trinket1))
                    {
                        StyxWoW.Me.Inventory.Equipped.Trinket1.Use();
                        Logging.Write("Activate " + StyxWoW.Me.Inventory.Equipped.Trinket1.Name +
                                      " on Burst Mode");
                    }
                    break;
                case 4:
                    if (LastBreakCC < DateTime.Now &&
                        Me.Inventory.Equipped.Trinket1 != null &&
                        !MeHasAura("Scatter Shot") &&
                        //!MeHasAura("Cheap Shot") &&
                        !MeHasAura("Sap") &&
                        DebuffCCDuration(Me, 3000, true) &&
                        CanUseCheck(Me.Inventory.Equipped.Trinket1))
                    {
                        StyxWoW.Me.Inventory.Equipped.Trinket1.Use();
                        Logging.Write("Activate " + StyxWoW.Me.Inventory.Equipped.Trinket1.Name +
                                      " on Lose Control");
                    }
                    break;
                case 5:
                    if (Me.Inventory.Equipped.Trinket1 != null &&
                        HealWeightMe < THSettings.Instance.Trinket1HP &&
                        CanUseCheck(Me.Inventory.Equipped.Trinket1))
                    {
                        StyxWoW.Me.Inventory.Equipped.Trinket1.Use();
                        Logging.Write("Activate " + StyxWoW.Me.Inventory.Equipped.Trinket1.Name +
                                      " on Low HP");
                    }
                    break;
                case 6:
                    if (UnitHealIsValid &&
                        HealWeightUnitHeal <= THSettings.Instance.Trinket1HP &&
                        Me.Combat &&
                        Me.Inventory.Equipped.Trinket1 != null &&
                        CanUseCheck(Me.Inventory.Equipped.Trinket1))
                    {
                        StyxWoW.Me.Inventory.Equipped.Trinket1.Use();
                        Logging.Write("Activate " + StyxWoW.Me.Inventory.Equipped.Trinket1.Name +
                                      " on Friendly Unit Low HP");
                    }
                    break;
                case 7:
                    if (Me.Inventory.Equipped.Trinket1 != null &&
                        CurrentTargetAttackable(20) &&
                        !Me.CurrentTarget.IsPet &&
                        Me.CurrentTarget.HealthPercent <= THSettings.Instance.Trinket1HP &&
                        CanUseCheck(Me.Inventory.Equipped.Trinket1))
                    {
                        StyxWoW.Me.Inventory.Equipped.Trinket1.Use();
                        Logging.Write("Activate " + StyxWoW.Me.Inventory.Equipped.Trinket1.Name +
                                      " on Enemy Unit Low HP");
                    }
                    break;
                case 8:
                    if (Me.Inventory.Equipped.Trinket1 != null &&
                        Me.ManaPercent <= THSettings.Instance.Trinket1HP &&
                        CanUseCheck(Me.Inventory.Equipped.Trinket1))
                    {
                        StyxWoW.Me.Inventory.Equipped.Trinket1.Use();
                        Logging.Write("Activate " + StyxWoW.Me.Inventory.Equipped.Trinket1.Name +
                                      " on Low Mana");
                    }
                    break;
                case 9:
                    if (Me.Combat &&
                        Me.Inventory.Equipped.Trinket1 != null &&
                        BuffBurst(Me) &&
                        CanUseCheck(Me.Inventory.Equipped.Trinket1))
                    {
                        StyxWoW.Me.Inventory.Equipped.Trinket1.Use();
                        Logging.Write("Activate " + StyxWoW.Me.Inventory.Equipped.Trinket1.Name +
                                      " on Using Cooldown");
                    }
                    break;
            }

            switch (THSettings.Instance.Trinket2)
            {
                case 1:
                    if (Me.Inventory.Equipped.Trinket2 != null &&
                        CanUseCheck(Me.Inventory.Equipped.Trinket2))
                    {
                        StyxWoW.Me.Inventory.Equipped.Trinket2.Use();
                        Logging.Write("Activate " + StyxWoW.Me.Inventory.Equipped.Trinket2.Name +
                                      " on Cooldown");
                    }
                    break;
                case 2:
                    if (CurrentTargetAttackable(30) &&
                        Me.CurrentTarget.IsBoss &&
                        Me.Inventory.Equipped.Trinket2 != null &&
                        CanUseCheck(Me.Inventory.Equipped.Trinket2))
                    {
                        StyxWoW.Me.Inventory.Equipped.Trinket2.Use();
                        Logging.Write("Activate " + StyxWoW.Me.Inventory.Equipped.Trinket2.Name +
                                      " on Cooldown (Boss Only");
                    }
                    break;
                case 3:
                    if (THSettings.Instance.Burst &&
                        Me.Inventory.Equipped.Trinket2 != null &&
                        CanUseCheck(Me.Inventory.Equipped.Trinket2))
                    {
                        StyxWoW.Me.Inventory.Equipped.Trinket2.Use();
                        Logging.Write("Activate " + StyxWoW.Me.Inventory.Equipped.Trinket2.Name +
                                      " on Burst Mode");
                    }
                    break;
                case 4:
                    if (LastBreakCC < DateTime.Now &&
                        Me.Inventory.Equipped.Trinket2 != null &&
                        !MeHasAura("Scatter Shot") &&
                        //!MeHasAura("Cheap Shot") &&
                        !MeHasAura("Sap") &&
                        DebuffCCDuration(Me, 3000, true) &&
                        CanUseCheck(Me.Inventory.Equipped.Trinket2))
                    {
                        StyxWoW.Me.Inventory.Equipped.Trinket2.Use();
                        Logging.Write("Activate " + StyxWoW.Me.Inventory.Equipped.Trinket2.Name +
                                      " on Lose Control");
                    }
                    break;
                case 5:
                    if (Me.Combat &&
                        Me.Inventory.Equipped.Trinket2 != null &&
                        HealWeightMe < THSettings.Instance.Trinket2HP &&
                        CanUseCheck(Me.Inventory.Equipped.Trinket2))
                    {
                        StyxWoW.Me.Inventory.Equipped.Trinket2.Use();
                        Logging.Write("Activate " + StyxWoW.Me.Inventory.Equipped.Trinket2.Name +
                                      " on Low HP");
                    }
                    break;
                case 6:
                    if (UnitHealIsValid &&
                        HealWeightUnitHeal <= THSettings.Instance.Trinket2HP &&
                        Me.Inventory.Equipped.Trinket2 != null &&
                        CanUseCheck(Me.Inventory.Equipped.Trinket2))
                    {
                        StyxWoW.Me.Inventory.Equipped.Trinket2.Use();
                        Logging.Write("Activate " + StyxWoW.Me.Inventory.Equipped.Trinket2.Name +
                                      " on Friendly Unit Low HP");
                    }
                    break;
                case 7:
                    if (Me.Inventory.Equipped.Trinket2 != null &&
                        CurrentTargetAttackable(20) &&
                        !Me.CurrentTarget.IsPet &&
                        Me.CurrentTarget.HealthPercent <= THSettings.Instance.Trinket2HP &&
                        CanUseCheck(Me.Inventory.Equipped.Trinket2))
                    {
                        StyxWoW.Me.Inventory.Equipped.Trinket2.Use();
                        Logging.Write("Activate " + StyxWoW.Me.Inventory.Equipped.Trinket2.Name +
                                      " on Enemy Unit Low HP");
                    }
                    break;
                case 8:
                    if (Me.Inventory.Equipped.Trinket2 != null &&
                        Me.ManaPercent <= THSettings.Instance.Trinket2HP &&
                        CanUseCheck(Me.Inventory.Equipped.Trinket2))
                    {
                        StyxWoW.Me.Inventory.Equipped.Trinket2.Use();
                        Logging.Write("Activate " + StyxWoW.Me.Inventory.Equipped.Trinket2.Name +
                                      " on Low Mana");
                    }
                    break;
                case 9:
                    if (Me.Inventory.Equipped.Trinket2 != null &&
                        BuffBurst(Me) &&
                        CanUseCheck(Me.Inventory.Equipped.Trinket2))
                    {
                        StyxWoW.Me.Inventory.Equipped.Trinket2.Use();
                        Logging.Write("Activate " + StyxWoW.Me.Inventory.Equipped.Trinket2.Name +
                                      " on Using Cooldown");
                    }
                    break;
            }
        }

        #endregion

        #region UseProfession

        private static Composite UseProfession()
        {
            return new Decorator(
                ret =>
                THSettings.Instance.ProfBuff == 1 &&
                //LastCastSpell != "SProfBuff" &&
                Me.Combat &&
                !Me.Mounted,
                new PrioritySelector(
                    //Engineering
                    new Decorator(
                        ret =>
                        THSettings.Instance.ProfBuff == 1 &&
                        //LastCastSpell != "SProfBuff" &&
                        Me.Inventory.Equipped.Hands != null &&
                        CanUseCheck(Me.Inventory.Equipped.Hands),
                        new Action(delegate
                            {
                                Logging.Write("Use: Gloves Buff Activated on Cooldown");
                                StyxWoW.Me.Inventory.Equipped.Hands.Use();
                                LastCastSpell = "SProfBuff";
                                return RunStatus.Failure;
                            })),
                    new Decorator(
                        ret =>
                        THSettings.Instance.ProfBuff == 2 &&
                        //LastCastSpell != "SProfBuff" &&
                        Me.Inventory.Equipped.Hands != null &&
                        CurrentTargetAttackable(30) &&
                        Me.CurrentTarget.IsBoss &&
                        CanUseCheck(Me.Inventory.Equipped.Hands),
                        new Action(delegate
                            {
                                Logging.Write("Use: Gloves Buff Activated on Cooldown (Boss Only");
                                StyxWoW.Me.Inventory.Equipped.Hands.Use();
                                LastCastSpell = "SProfBuff";
                                return RunStatus.Failure;
                            })),
                    new Decorator(
                        ret =>
                        THSettings.Instance.ProfBuff == 3 &&
                        //LastCastSpell != "SProfBuff" &&
                        THSettings.Instance.Burst &&
                        Me.Inventory.Equipped.Hands != null &&
                        CanUseCheck(Me.Inventory.Equipped.Hands),
                        new Action(delegate
                            {
                                Logging.Write("Use: Gloves Buff Activated on Burst Mode");
                                StyxWoW.Me.Inventory.Equipped.Hands.Use();
                                LastCastSpell = "SProfBuff";
                                return RunStatus.Failure;
                            })),
                    new Decorator(
                        ret =>
                        THSettings.Instance.ProfBuff == 4 &&
                        //LastCastSpell != "SProfBuff" &&
                        Me.Inventory.Equipped.Hands != null &&
                        CurrentTargetAttackable(30) &&
                        DebuffCCDuration(Me, 3000) &&
                        CanUseCheck(Me.Inventory.Equipped.Hands),
                        new Action(delegate
                            {
                                Logging.Write("Use: Gloves Buff Activated on Lose Control");
                                StyxWoW.Me.Inventory.Equipped.Hands.Use();
                                LastCastSpell = "SProfBuff";
                                return RunStatus.Failure;
                            })),
                    new Decorator(
                        ret =>
                        THSettings.Instance.ProfBuff == 5 &&
                        //LastCastSpell != "SProfBuff" &&
                        Me.Inventory.Equipped.Hands != null &&
                        HealWeightMe < THSettings.Instance.ProfBuffHP &&
                        CanUseCheck(Me.Inventory.Equipped.Hands),
                        new Action(delegate
                            {
                                Logging.Write("Use: GLoves Buff Activated on Low HP");
                                StyxWoW.Me.Inventory.Equipped.Hands.Use();
                                LastCastSpell = "SProfBuff";
                                return RunStatus.Failure;
                            })),
                    new Decorator(
                        ret =>
                        THSettings.Instance.ProfBuff == 6 &&
                        UnitHealIsValid &&
                        HealWeightUnitHeal <= THSettings.Instance.ProfBuffHP &&
                        //LastCastSpell != "SProfBuff" &&
                        Me.Inventory.Equipped.Hands != null &&
                        CanUseCheck(Me.Inventory.Equipped.Hands),
                        new Action(delegate
                            {
                                Logging.Write("Use: Gloves Buff Activated on Friendly Unit Low HP");
                                StyxWoW.Me.Inventory.Equipped.Hands.Use();
                                LastCastSpell = "SProfBuff";
                                return RunStatus.Failure;
                            })),
                    new Decorator(
                        ret =>
                        THSettings.Instance.ProfBuff == 7 &&
                        //LastCastSpell != "SProfBuff" &&
                        Me.Inventory.Equipped.Hands != null &&
                        CurrentTargetAttackable(20) &&
                        !Me.CurrentTarget.IsPet &&
                        Me.CurrentTarget.HealthPercent <= THSettings.Instance.ProfBuffHP &&
                        CanUseCheck(Me.Inventory.Equipped.Hands),
                        new Action(delegate
                            {
                                Logging.Write("Use: Gloves Buff Activated on Enemy Unit Low HP");
                                StyxWoW.Me.Inventory.Equipped.Hands.Use();
                                LastCastSpell = "SProfBuff";
                                return RunStatus.Failure;
                            })),
                    new Decorator(
                        ret =>
                        THSettings.Instance.ProfBuff == 8 &&
                        //LastCastSpell != "SProfBuff" &&
                        Me.Inventory.Equipped.Hands != null &&
                        Me.ManaPercent <= THSettings.Instance.ProfBuffHP &&
                        CanUseCheck(Me.Inventory.Equipped.Hands),
                        new Action(delegate
                            {
                                Logging.Write("Use: Gloves Buff Activated on Low Mana");
                                StyxWoW.Me.Inventory.Equipped.Hands.Use();
                                LastCastSpell = "SProfBuff";
                                return RunStatus.Failure;
                            })),
                    new Decorator(
                        ret =>
                        THSettings.Instance.ProfBuff == 9 &&
                        //LastCastSpell != "SProfBuff" &&
                        Me.Inventory.Equipped.Hands != null &&
                        BuffBurst(Me) &&
                        CanUseCheck(Me.Inventory.Equipped.Hands),
                        new Action(delegate
                            {
                                Logging.Write("Use: Gloves Buff Activated on Using Cooldown");
                                StyxWoW.Me.Inventory.Equipped.Hands.Use();
                                LastCastSpell = "SProfBuff";
                                return RunStatus.Failure;
                            })),
                    //Herbalism
                    new Decorator(
                        ret =>
                        THSettings.Instance.ProfBuff == 1 &&
                        //SSpellManager.HasSpell("Lifeblood") &&
                        //LastCastSpell != "Lifeblood" &&
                        CanCastCheck("Lifeblood", true),
                        new Action(delegate
                            {
                                Logging.Write("Use: Lifeblood Activated on Cooldown");
                                CastSpell("Lifeblood", Me);
                                return RunStatus.Failure;
                            })),
                    new Decorator(
                        ret =>
                        THSettings.Instance.ProfBuff == 2 &&
                        //SSpellManager.HasSpell("Lifeblood") &&
                        //LastCastSpell != "Lifeblood" &&
                        CurrentTargetAttackable(30) &&
                        Me.CurrentTarget.IsBoss &&
                        CanCastCheck("Lifeblood", true),
                        new Action(delegate
                            {
                                Logging.Write("Use: Lifeblood Activated on Cooldown (Boss Only");
                                CastSpell("Lifeblood", Me);
                                return RunStatus.Failure;
                            })),
                    new Decorator(
                        ret =>
                        THSettings.Instance.ProfBuff == 3 &&
                        //SSpellManager.HasSpell("Lifeblood") &&
                        //LastCastSpell != "Lifeblood" &&
                        THSettings.Instance.Burst &&
                        CanCastCheck("Lifeblood", true),
                        new Action(delegate
                            {
                                Logging.Write("Use: Lifeblood Activated on Burst Mode");
                                CastSpell("Lifeblood", Me);
                                return RunStatus.Failure;
                            })),
                    new Decorator(
                        ret =>
                        THSettings.Instance.ProfBuff == 4 &&
                        //SSpellManager.HasSpell("Lifeblood") &&
                        //LastCastSpell != "Lifeblood" &&
                        Me.Combat &&
                        DebuffCCDuration(Me, 3000) &&
                        CanCastCheck("Lifeblood", true),
                        new Action(delegate
                            {
                                Logging.Write("Use: Lifeblood Activated on Lose Control");
                                CastSpell("Lifeblood", Me);
                                return RunStatus.Failure;
                            })),
                    new Decorator(
                        ret =>
                        THSettings.Instance.ProfBuff == 5 &&
                        //SSpellManager.HasSpell("Lifeblood") &&
                        //LastCastSpell != "Lifeblood" &&
                        HealWeightMe <= THSettings.Instance.ProfBuffHP &&
                        CanCastCheck("Lifeblood", true),
                        new Action(delegate
                            {
                                Logging.Write("Use: Lifeblood Activated on Low HP");
                                CastSpell("Lifeblood", Me);
                                return RunStatus.Failure;
                            })),
                    new Decorator(
                        ret =>
                        THSettings.Instance.ProfBuff == 6 &&
                        UnitHealIsValid &&
                        HealWeightUnitHeal <= THSettings.Instance.ProfBuffHP &&
                        //SSpellManager.HasSpell("Lifeblood") &&
                        //LastCastSpell != "Lifeblood" &&
                        CanCastCheck("Lifeblood", true),
                        new Action(delegate
                            {
                                Logging.Write("Use: Lifeblood Activated on Friendly Unit Low HP");
                                CastSpell("Lifeblood", Me);
                                return RunStatus.Failure;
                            })),
                    new Decorator(
                        ret =>
                        THSettings.Instance.ProfBuff == 7 &&
                        //SSpellManager.HasSpell("Lifeblood") &&
                        //LastCastSpell != "Lifeblood" &&
                        CurrentTargetAttackable(20) &&
                        !Me.CurrentTarget.IsPet &&
                        Me.CurrentTarget.HealthPercent <= THSettings.Instance.ProfBuffHP &&
                        CanCastCheck("Lifeblood", true),
                        new Action(delegate
                            {
                                Logging.Write("Use: Lifeblood Activated on Enemy Unit Low HP");
                                CastSpell("Lifeblood", Me);
                                return RunStatus.Failure;
                            })),
                    new Decorator(
                        ret =>
                        THSettings.Instance.ProfBuff == 8 &&
                        //SSpellManager.HasSpell("Lifeblood") &&
                        //LastCastSpell != "Lifeblood" &&
                        Me.ManaPercent <= THSettings.Instance.ProfBuffHP &&
                        CanCastCheck("Lifeblood", true),
                        new Action(delegate
                            {
                                Logging.Write("Use: Lifeblood Activated on Low Mana");
                                CastSpell("Lifeblood", Me);
                                return RunStatus.Failure;
                            })),
                    new Decorator(
                        ret =>
                        THSettings.Instance.ProfBuff == 9 &&
                        //SSpellManager.HasSpell("Lifeblood") &&
                        //LastCastSpell != "Lifeblood" &&
                        BuffBurst(Me) &&
                        CanCastCheck("Lifeblood", true),
                        new Action(delegate
                            {
                                Logging.Write("Use: Lifeblood Activated on Using Cooldown");
                                CastSpell("Lifeblood", Me);
                                return RunStatus.Failure;
                            })))
                );
        }

        #endregion

        #region WarStomp

        private static WoWUnit UnitWarStomp;
        private static DateTime LastInterrupt;

        private static bool GetUnitWarStomp()
        {
            UnitWarStomp = null;

            if (InBattleground || InArena)
            {
                UnitWarStomp = NearbyUnFriendlyPlayers.FirstOrDefault(
                    unit => BasicCheck(unit) &&
                            (THSettings.Instance.InterruptAll ||
                             THSettings.Instance.InterruptTarget &&
                             Me.CurrentTarget != null &&
                             unit == Me.CurrentTarget ||
                             THSettings.Instance.InterruptFocus &&
                             Me.FocusedUnit != null &&
                             unit == Me.FocusedUnit) &&
                            InterruptCheck(unit, THSettings.Instance.RebukeMs + MyLatency) &&
                            Attackable(unit, 8));
            }
                //PvE Search
            else
            {
                UnitWarStomp = NearbyUnFriendlyUnits.FirstOrDefault(
                    unit => BasicCheck(unit) &&
                            (THSettings.Instance.InterruptAll ||
                             THSettings.Instance.InterruptTarget &&
                             Me.CurrentTarget != null &&
                             unit == Me.CurrentTarget ||
                             THSettings.Instance.InterruptFocus &&
                             Me.FocusedUnit != null &&
                             unit == Me.FocusedUnit) &&
                            FarFriendlyPlayers.Contains(unit.CurrentTarget) &&
                            InterruptCheck(unit, THSettings.Instance.RebukeMs + MyLatency) &&
                            Attackable(unit, 8));
            }

            return BasicCheck(UnitWarStomp);
        }

        private void WarStompVoid()
        {
            if (THSettings.Instance.AutoRacial &&
                HealWeightUnitHeal > THSettings.Instance.PriorityHeal &&
                //S//SSpellManager.HasSpell("War Stomp") &&
                LastInterrupt < DateTime.Now &&
                UnitHeal != null &&
                UnitHeal.IsValid &&
                !IsMoving(Me) &&
                CanCastCheck("War Stomp") &&
                GetUnitWarStomp())
            {
                if (Me.IsCasting || Me.IsChanneling)
                {
                    SpellManager.StopCasting();
                }


                while (BasicCheck(UnitWarStomp) &&
                       UnitWarStomp.CurrentCastTimeLeft.TotalMilliseconds >
                       THSettings.Instance.RebukeMs + 500)
                {
                    Logging.Write("Waiting for War Stomp");
                }

                if (UnitWarStomp.IsCasting || UnitWarStomp.IsChanneling)
                {
                    CastSpell("War Stomp", Me, "War Stomp");
                    LastInterrupt = DateTime.Now + TimeSpan.FromMilliseconds(1500);
                }
            }
        }

        #endregion

        #region WordofGlory

        private static Composite WordofGlory()
        {
            return new Decorator(
                ret =>
                THSettings.Instance.WordofGloryHoly &&
                //SSpellManager.HasSpell("Word of Glory") &&
                (PlayerHolyPower >= 3 ||
                 MeHasAura(90174)) &&
                (HealWeightUnitHeal <= THSettings.Instance.WordofGloryHolyHP ||
                 MeHasAura(90174) &&
                 MyAuraTimeLeft(90174, Me) < 3000) &&
                Healable(UnitHeal) &&
                CanCastCheck("Word of Glory"),
                new Action(delegate { CastSpell("Word of Glory", UnitHeal); }));
        }

        #endregion

        #region WordofGloryMeTopUpRet

        private static Composite WordofGloryMeTopUpRet()
        {
            return new Decorator(
                ret =>
                //SSpellManager.HasSpell("Word of Glory") &&
                ////!Me.Mounted &&
                !Me.Combat &&
                (PlayerHolyPower >= 1 ||
                 MeHasAura(90174)) &&
                !InDungeon &&
                !InRaid &&
                HealWeightMe <= THSettings.Instance.DoNotHealAbove &&
                MyAuraTimeLeft(114163, Me) < 1000 &&
                CanCastCheck("Word of Glory"), //114163 Eternal Flame
                new Action(delegate { CastSpell("Word of Glory", Me); })
                );
        }

        #endregion

        #region WordofGloryMeRet

        private static Composite WordofGloryMeRet()
        {
            return new Decorator(
                ret =>
                THSettings.Instance.WordofGloryMeRet &&
                //SSpellManager.HasSpell("Word of Glory") &&
                ////!Me.Mounted &&
                Me.Combat &&
                (PlayerHolyPower >= 3 ||
                 MeHasAura(90174)) &&
                !InDungeon &&
                !InRaid &&
                HealWeightMe <= THSettings.Instance.WordofGloryMeRetHP &&
                MyAuraTimeLeft(114163, Me) < 2000 &&
                CanCastCheck("Word of Glory"), //114163 Eternal Flame
                new Action(delegate { CastSpell("Word of Glory", Me); })
                );
        }

        #endregion

        #region WordofGloryMeProtection

        private static Composite WordofGloryMeProt()
        {
            return new Decorator(
                ret =>
                THSettings.Instance.WordofGloryMeProt &&
                //SSpellManager.HasSpell("Word of Glory") &&
                ////!Me.Mounted &&
                Me.Combat &&
                (PlayerHolyPower >= THSettings.Instance.WordofGloryMeProtHolyPower ||
                 MeHasAura(90174)) &&
                HealWeightMe <= THSettings.Instance.WordofGloryMeProtHP &&
                MyAuraTimeLeft(114163, Me) < 2000 && //114163 Eternal Flame
                CanCastCheck("Word of Glory", true),
                new Action(delegate
                    {
                        CastSpell("Word of Glory", Me, "WordofGloryMeProt");
                        return RunStatus.Failure;
                    })
                );
        }

        private static Composite WordofGloryFriendProt()
        {
            return new Decorator(
                ret =>
                THSettings.Instance.WordofGloryFriendProt &&
                //S//SSpellManager.HasSpell("Word of Glory") &&
                ////!Me.Mounted &&
                Me.Combat &&
                (PlayerHolyPower >= THSettings.Instance.WordofGloryFriendProtHolyPower ||
                 MeHasAura(90174)) &&
                HealWeightUnitHeal <= THSettings.Instance.WordofGloryFriendProtHP &&
                MyAuraTimeLeft(114163, UnitHeal) < 2000 && //114163 Eternal Flame
                CanCastCheck("Word of Glory", true),
                new Action(delegate
                    {
                        CastSpell("Word of Glory", UnitHeal);
                        return RunStatus.Failure;
                    })
                );
        }

        #endregion

        #region WordofGloryFriendRet

        private static Composite WordofGloryFriendRet()
        {
            return new Decorator(
                ret =>
                THSettings.Instance.WordofGloryFriendRet &&
                //S//SSpellManager.HasSpell("Word of Glory") &&
                ////!Me.Mounted &&
                Me.Combat &&
                (PlayerHolyPower >= 3 ||
                 MeHasAura(90174)) &&
                !InDungeon &&
                !InRaid &&
                UnitHeal != null &&
                UnitHeal.IsValid &&
                HealWeightUnitHeal <= THSettings.Instance.WordofGloryFriendRetHP &&
                MyAuraTimeLeft(114163, UnitHeal) < 2000 &&
                CanCastCheck("Word of Glory"), //114163 Eternal Flame
                new Action(delegate { CastSpell("Word of Glory", UnitHeal); })
                );
        }

        #endregion

        #region WriteDebug

        private static DateTime LastWriteDebug;
        private static bool WriteDebugEnable;

        private static Composite WriteDebug(string message)
        {
            return new Decorator(ret => WriteDebugEnable,
                                 new Action(delegate
                                     {
                                         Logging.Write("(" +
                                                       Math.Round(
                                                           (DateTime.Now - LastWriteDebug).TotalMilliseconds,
                                                           0) +
                                                       ") " + message);
                                         LastWriteDebug = DateTime.Now;
                                         return RunStatus.Failure;
                                     }));
        }

        #endregion

        #region TemplarsVerdictBurst

        private static Composite TemplarsVerdictBurst()
        {
            return new Decorator(
                ret =>
                THSettings.Instance.TemplarsVerdict &&
                //S//SSpellManager.HasSpell("Templar's Verdict") &&
                ////!Me.Mounted &&
                !MeHasAura("Hand of Protection") &&
                CurrentTargetAttackable(5) &&
                FacingOverride(Me.CurrentTarget) &&
                ((PlayerHolyPower >= 3 &&
                  DebuffStunDuration(Me.CurrentTarget,300) &&
                  HealWeightMe > 30) ||
                 MeHasAura(90174) ||
                 PlayerHolyPower >= 3 &&
                 MeHasAura("Holy Avenger")) &&
                CanCastCheck("Templar's Verdict"),
                new Action(delegate
                {
                    SafelyFacingTarget(Me.CurrentTarget);
                    CastSpell("Templar's Verdict", Me.CurrentTarget);
                }));
        }

        #endregion

    }
}